//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2022 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

import Foundation
import SotoCore

extension Drs {
    // MARK: Enums

    public enum DataReplicationErrorString: String, CustomStringConvertible, Codable, _SotoSendable {
        case agentNotSeen = "AGENT_NOT_SEEN"
        case failedToAttachStagingDisks = "FAILED_TO_ATTACH_STAGING_DISKS"
        case failedToAuthenticateWithService = "FAILED_TO_AUTHENTICATE_WITH_SERVICE"
        case failedToBootReplicationServer = "FAILED_TO_BOOT_REPLICATION_SERVER"
        case failedToConnectAgentToReplicationServer = "FAILED_TO_CONNECT_AGENT_TO_REPLICATION_SERVER"
        case failedToCreateSecurityGroup = "FAILED_TO_CREATE_SECURITY_GROUP"
        case failedToCreateStagingDisks = "FAILED_TO_CREATE_STAGING_DISKS"
        case failedToDownloadReplicationSoftware = "FAILED_TO_DOWNLOAD_REPLICATION_SOFTWARE"
        case failedToLaunchReplicationServer = "FAILED_TO_LAUNCH_REPLICATION_SERVER"
        case failedToPairReplicationServerWithAgent = "FAILED_TO_PAIR_REPLICATION_SERVER_WITH_AGENT"
        case failedToStartDataTransfer = "FAILED_TO_START_DATA_TRANSFER"
        case notConverging = "NOT_CONVERGING"
        case snapshotsFailure = "SNAPSHOTS_FAILURE"
        case unstableNetwork = "UNSTABLE_NETWORK"
        public var description: String { return self.rawValue }
    }

    public enum DataReplicationInitiationStepName: String, CustomStringConvertible, Codable, _SotoSendable {
        case attachStagingDisks = "ATTACH_STAGING_DISKS"
        case authenticateWithService = "AUTHENTICATE_WITH_SERVICE"
        case bootReplicationServer = "BOOT_REPLICATION_SERVER"
        case connectAgentToReplicationServer = "CONNECT_AGENT_TO_REPLICATION_SERVER"
        case createSecurityGroup = "CREATE_SECURITY_GROUP"
        case createStagingDisks = "CREATE_STAGING_DISKS"
        case downloadReplicationSoftware = "DOWNLOAD_REPLICATION_SOFTWARE"
        case launchReplicationServer = "LAUNCH_REPLICATION_SERVER"
        case pairReplicationServerWithAgent = "PAIR_REPLICATION_SERVER_WITH_AGENT"
        case startDataTransfer = "START_DATA_TRANSFER"
        case wait = "WAIT"
        public var description: String { return self.rawValue }
    }

    public enum DataReplicationInitiationStepStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case failed = "FAILED"
        case inProgress = "IN_PROGRESS"
        case notStarted = "NOT_STARTED"
        case skipped = "SKIPPED"
        case succeeded = "SUCCEEDED"
        public var description: String { return self.rawValue }
    }

    public enum DataReplicationState: String, CustomStringConvertible, Codable, _SotoSendable {
        case backlog = "BACKLOG"
        case continuous = "CONTINUOUS"
        case creatingSnapshot = "CREATING_SNAPSHOT"
        case disconnected = "DISCONNECTED"
        case initialSync = "INITIAL_SYNC"
        case initiating = "INITIATING"
        case paused = "PAUSED"
        case rescan = "RESCAN"
        case stalled = "STALLED"
        case stopped = "STOPPED"
        public var description: String { return self.rawValue }
    }

    public enum EC2InstanceState: String, CustomStringConvertible, Codable, _SotoSendable {
        case notFound = "NOT_FOUND"
        case pending = "PENDING"
        case running = "RUNNING"
        case shuttingDown = "SHUTTING-DOWN"
        case stopped = "STOPPED"
        case stopping = "STOPPING"
        case terminated = "TERMINATED"
        public var description: String { return self.rawValue }
    }

    public enum ExtensionStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case extended = "EXTENDED"
        case extensionError = "EXTENSION_ERROR"
        case notExtended = "NOT_EXTENDED"
        public var description: String { return self.rawValue }
    }

    public enum FailbackLaunchType: String, CustomStringConvertible, Codable, _SotoSendable {
        case drill = "DRILL"
        case recovery = "RECOVERY"
        public var description: String { return self.rawValue }
    }

    public enum FailbackReplicationError: String, CustomStringConvertible, Codable, _SotoSendable {
        case agentNotSeen = "AGENT_NOT_SEEN"
        case failbackClientNotSeen = "FAILBACK_CLIENT_NOT_SEEN"
        case failedGettingReplicationState = "FAILED_GETTING_REPLICATION_STATE"
        case failedToAttachStagingDisks = "FAILED_TO_ATTACH_STAGING_DISKS"
        case failedToAuthenticateWithService = "FAILED_TO_AUTHENTICATE_WITH_SERVICE"
        case failedToBootReplicationServer = "FAILED_TO_BOOT_REPLICATION_SERVER"
        case failedToConfigureReplicationSoftware = "FAILED_TO_CONFIGURE_REPLICATION_SOFTWARE"
        case failedToConnectAgentToReplicationServer = "FAILED_TO_CONNECT_AGENT_TO_REPLICATION_SERVER"
        case failedToCreateSecurityGroup = "FAILED_TO_CREATE_SECURITY_GROUP"
        case failedToCreateStagingDisks = "FAILED_TO_CREATE_STAGING_DISKS"
        case failedToDownloadReplicationSoftware = "FAILED_TO_DOWNLOAD_REPLICATION_SOFTWARE"
        case failedToDownloadReplicationSoftwareToFailbackClient = "FAILED_TO_DOWNLOAD_REPLICATION_SOFTWARE_TO_FAILBACK_CLIENT"
        case failedToEstablishAgentReplicatorSoftwareCommunication = "FAILED_TO_ESTABLISH_AGENT_REPLICATOR_SOFTWARE_COMMUNICATION"
        case failedToEstablishRecoveryInstanceCommunication = "FAILED_TO_ESTABLISH_RECOVERY_INSTANCE_COMMUNICATION"
        case failedToLaunchReplicationServer = "FAILED_TO_LAUNCH_REPLICATION_SERVER"
        case failedToPairAgentWithReplicationSoftware = "FAILED_TO_PAIR_AGENT_WITH_REPLICATION_SOFTWARE"
        case failedToPairReplicationServerWithAgent = "FAILED_TO_PAIR_REPLICATION_SERVER_WITH_AGENT"
        case failedToStartDataTransfer = "FAILED_TO_START_DATA_TRANSFER"
        case notConverging = "NOT_CONVERGING"
        case snapshotsFailure = "SNAPSHOTS_FAILURE"
        case unstableNetwork = "UNSTABLE_NETWORK"
        public var description: String { return self.rawValue }
    }

    public enum FailbackState: String, CustomStringConvertible, Codable, _SotoSendable {
        case failbackCompleted = "FAILBACK_COMPLETED"
        case failbackError = "FAILBACK_ERROR"
        case failbackInProgress = "FAILBACK_IN_PROGRESS"
        case failbackLaunchStateNotAvailable = "FAILBACK_LAUNCH_STATE_NOT_AVAILABLE"
        case failbackNotReadyForLaunch = "FAILBACK_NOT_READY_FOR_LAUNCH"
        case failbackNotStarted = "FAILBACK_NOT_STARTED"
        case failbackReadyForLaunch = "FAILBACK_READY_FOR_LAUNCH"
        public var description: String { return self.rawValue }
    }

    public enum InitiatedBy: String, CustomStringConvertible, Codable, _SotoSendable {
        case diagnostic = "DIAGNOSTIC"
        case failback = "FAILBACK"
        case startDrill = "START_DRILL"
        case startRecovery = "START_RECOVERY"
        case targetAccount = "TARGET_ACCOUNT"
        case terminateRecoveryInstances = "TERMINATE_RECOVERY_INSTANCES"
        public var description: String { return self.rawValue }
    }

    public enum JobLogEvent: String, CustomStringConvertible, Codable, _SotoSendable {
        case cleanupEnd = "CLEANUP_END"
        case cleanupFail = "CLEANUP_FAIL"
        case cleanupStart = "CLEANUP_START"
        case conversionEnd = "CONVERSION_END"
        case conversionFail = "CONVERSION_FAIL"
        case conversionStart = "CONVERSION_START"
        case jobCancel = "JOB_CANCEL"
        case jobEnd = "JOB_END"
        case jobStart = "JOB_START"
        case launchFailed = "LAUNCH_FAILED"
        case launchStart = "LAUNCH_START"
        case serverSkipped = "SERVER_SKIPPED"
        case snapshotEnd = "SNAPSHOT_END"
        case snapshotFail = "SNAPSHOT_FAIL"
        case snapshotStart = "SNAPSHOT_START"
        case usingPreviousSnapshot = "USING_PREVIOUS_SNAPSHOT"
        case usingPreviousSnapshotFailed = "USING_PREVIOUS_SNAPSHOT_FAILED"
        public var description: String { return self.rawValue }
    }

    public enum JobStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case completed = "COMPLETED"
        case pending = "PENDING"
        case started = "STARTED"
        public var description: String { return self.rawValue }
    }

    public enum JobType: String, CustomStringConvertible, Codable, _SotoSendable {
        case createConvertedSnapshot = "CREATE_CONVERTED_SNAPSHOT"
        case launch = "LAUNCH"
        case terminate = "TERMINATE"
        public var description: String { return self.rawValue }
    }

    public enum LastLaunchResult: String, CustomStringConvertible, Codable, _SotoSendable {
        case failed = "FAILED"
        case notStarted = "NOT_STARTED"
        case pending = "PENDING"
        case succeeded = "SUCCEEDED"
        public var description: String { return self.rawValue }
    }

    public enum LastLaunchType: String, CustomStringConvertible, Codable, _SotoSendable {
        case drill = "DRILL"
        case recovery = "RECOVERY"
        public var description: String { return self.rawValue }
    }

    public enum LaunchDisposition: String, CustomStringConvertible, Codable, _SotoSendable {
        case started = "STARTED"
        case stopped = "STOPPED"
        public var description: String { return self.rawValue }
    }

    public enum LaunchStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case failed = "FAILED"
        case inProgress = "IN_PROGRESS"
        case launched = "LAUNCHED"
        case pending = "PENDING"
        case terminated = "TERMINATED"
        public var description: String { return self.rawValue }
    }

    public enum OriginEnvironment: String, CustomStringConvertible, Codable, _SotoSendable {
        case aws = "AWS"
        case onPremises = "ON_PREMISES"
        public var description: String { return self.rawValue }
    }

    public enum PITPolicyRuleUnits: String, CustomStringConvertible, Codable, _SotoSendable {
        case day = "DAY"
        case hour = "HOUR"
        case minute = "MINUTE"
        public var description: String { return self.rawValue }
    }

    public enum RecoveryInstanceDataReplicationInitiationStepName: String, CustomStringConvertible, Codable, _SotoSendable {
        case attachStagingDisks = "ATTACH_STAGING_DISKS"
        case authenticateWithService = "AUTHENTICATE_WITH_SERVICE"
        case bootReplicationServer = "BOOT_REPLICATION_SERVER"
        case completeVolumeMapping = "COMPLETE_VOLUME_MAPPING"
        case configureReplicationSoftware = "CONFIGURE_REPLICATION_SOFTWARE"
        case connectAgentToReplicationServer = "CONNECT_AGENT_TO_REPLICATION_SERVER"
        case createSecurityGroup = "CREATE_SECURITY_GROUP"
        case createStagingDisks = "CREATE_STAGING_DISKS"
        case downloadReplicationSoftware = "DOWNLOAD_REPLICATION_SOFTWARE"
        case downloadReplicationSoftwareToFailbackClient = "DOWNLOAD_REPLICATION_SOFTWARE_TO_FAILBACK_CLIENT"
        case establishAgentReplicatorSoftwareCommunication = "ESTABLISH_AGENT_REPLICATOR_SOFTWARE_COMMUNICATION"
        case establishRecoveryInstanceCommunication = "ESTABLISH_RECOVERY_INSTANCE_COMMUNICATION"
        case launchReplicationServer = "LAUNCH_REPLICATION_SERVER"
        case linkFailbackClientWithRecoveryInstance = "LINK_FAILBACK_CLIENT_WITH_RECOVERY_INSTANCE"
        case pairAgentWithReplicationSoftware = "PAIR_AGENT_WITH_REPLICATION_SOFTWARE"
        case pairReplicationServerWithAgent = "PAIR_REPLICATION_SERVER_WITH_AGENT"
        case startDataTransfer = "START_DATA_TRANSFER"
        case wait = "WAIT"
        public var description: String { return self.rawValue }
    }

    public enum RecoveryInstanceDataReplicationInitiationStepStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case failed = "FAILED"
        case inProgress = "IN_PROGRESS"
        case notStarted = "NOT_STARTED"
        case skipped = "SKIPPED"
        case succeeded = "SUCCEEDED"
        public var description: String { return self.rawValue }
    }

    public enum RecoveryInstanceDataReplicationState: String, CustomStringConvertible, Codable, _SotoSendable {
        case backlog = "BACKLOG"
        case continuous = "CONTINUOUS"
        case creatingSnapshot = "CREATING_SNAPSHOT"
        case disconnected = "DISCONNECTED"
        case initialSync = "INITIAL_SYNC"
        case initiating = "INITIATING"
        case notStarted = "NOT_STARTED"
        case paused = "PAUSED"
        case replicationStateNotAvailable = "REPLICATION_STATE_NOT_AVAILABLE"
        case rescan = "RESCAN"
        case stalled = "STALLED"
        case stopped = "STOPPED"
        public var description: String { return self.rawValue }
    }

    public enum RecoverySnapshotsOrder: String, CustomStringConvertible, Codable, _SotoSendable {
        case asc = "ASC"
        case desc = "DESC"
        public var description: String { return self.rawValue }
    }

    public enum ReplicationConfigurationDataPlaneRouting: String, CustomStringConvertible, Codable, _SotoSendable {
        case privateIp = "PRIVATE_IP"
        case publicIp = "PUBLIC_IP"
        public var description: String { return self.rawValue }
    }

    public enum ReplicationConfigurationDefaultLargeStagingDiskType: String, CustomStringConvertible, Codable, _SotoSendable {
        case auto = "AUTO"
        case gp2 = "GP2"
        case gp3 = "GP3"
        case st1 = "ST1"
        public var description: String { return self.rawValue }
    }

    public enum ReplicationConfigurationEbsEncryption: String, CustomStringConvertible, Codable, _SotoSendable {
        case custom = "CUSTOM"
        case `default` = "DEFAULT"
        public var description: String { return self.rawValue }
    }

    public enum ReplicationConfigurationReplicatedDiskStagingDiskType: String, CustomStringConvertible, Codable, _SotoSendable {
        case auto = "AUTO"
        case gp2 = "GP2"
        case gp3 = "GP3"
        case io1 = "IO1"
        case sc1 = "SC1"
        case st1 = "ST1"
        case standard = "STANDARD"
        public var description: String { return self.rawValue }
    }

    public enum ReplicationDirection: String, CustomStringConvertible, Codable, _SotoSendable {
        case failback = "FAILBACK"
        case failover = "FAILOVER"
        public var description: String { return self.rawValue }
    }

    public enum TargetInstanceTypeRightSizingMethod: String, CustomStringConvertible, Codable, _SotoSendable {
        case basic = "BASIC"
        case none = "NONE"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct Account: AWSDecodableShape {
        /// Account ID of AWS account.
        public let accountID: String?

        public init(accountID: String? = nil) {
            self.accountID = accountID
        }

        private enum CodingKeys: String, CodingKey {
            case accountID
        }
    }

    public struct CPU: AWSDecodableShape {
        /// The number of CPU cores.
        public let cores: Int64?
        /// The model name of the CPU.
        public let modelName: String?

        public init(cores: Int64? = nil, modelName: String? = nil) {
            self.cores = cores
            self.modelName = modelName
        }

        private enum CodingKeys: String, CodingKey {
            case cores
            case modelName
        }
    }

    public struct ConversionProperties: AWSDecodableShape {
        /// The timestamp of when the snapshot being converted was taken
        public let dataTimestamp: String?
        /// Whether the volume being converted uses UEFI or not
        public let forceUefi: Bool?
        /// The root volume name of a conversion job
        public let rootVolumeName: String?
        /// A mapping between the volumes being converted and the converted snapshot ids
        public let volumeToConversionMap: [String: [String: String]]?
        /// A mapping between the volumes and their sizes
        public let volumeToVolumeSize: [String: Int64]?

        public init(dataTimestamp: String? = nil, forceUefi: Bool? = nil, rootVolumeName: String? = nil, volumeToConversionMap: [String: [String: String]]? = nil, volumeToVolumeSize: [String: Int64]? = nil) {
            self.dataTimestamp = dataTimestamp
            self.forceUefi = forceUefi
            self.rootVolumeName = rootVolumeName
            self.volumeToConversionMap = volumeToConversionMap
            self.volumeToVolumeSize = volumeToVolumeSize
        }

        private enum CodingKeys: String, CodingKey {
            case dataTimestamp
            case forceUefi
            case rootVolumeName
            case volumeToConversionMap
            case volumeToVolumeSize
        }
    }

    public struct CreateExtendedSourceServerRequest: AWSEncodableShape {
        /// This defines the ARN of the source server in staging Account based on which you want to create an extended source server.
        public let sourceServerArn: String
        /// A list of tags associated with the extended source server.
        public let tags: [String: String]?

        public init(sourceServerArn: String, tags: [String: String]? = nil) {
            self.sourceServerArn = sourceServerArn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.sourceServerArn, name: "sourceServerArn", parent: name, max: 2048)
            try self.validate(self.sourceServerArn, name: "sourceServerArn", parent: name, min: 20)
            try self.validate(self.sourceServerArn, name: "sourceServerArn", parent: name, pattern: "^arn:(?:[0-9a-zA-Z_-]+:){3}([0-9]{12,}):source-server/(s-[0-9a-zA-Z]{17})$")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case sourceServerArn
            case tags
        }
    }

    public struct CreateExtendedSourceServerResponse: AWSDecodableShape {
        /// Created extended source server.
        public let sourceServer: SourceServer?

        public init(sourceServer: SourceServer? = nil) {
            self.sourceServer = sourceServer
        }

        private enum CodingKeys: String, CodingKey {
            case sourceServer
        }
    }

    public struct CreateReplicationConfigurationTemplateRequest: AWSEncodableShape {
        /// Whether to associate the default Elastic Disaster Recovery Security group with the Replication Configuration Template.
        public let associateDefaultSecurityGroup: Bool
        /// Configure bandwidth throttling for the outbound data transfer rate of the Source Server in Mbps.
        public let bandwidthThrottling: Int64
        /// Whether to create a Public IP for the Recovery Instance by default.
        public let createPublicIP: Bool
        /// The data plane routing mechanism that will be used for replication.
        public let dataPlaneRouting: ReplicationConfigurationDataPlaneRouting
        /// The Staging Disk EBS volume type to be used during replication.
        public let defaultLargeStagingDiskType: ReplicationConfigurationDefaultLargeStagingDiskType
        /// The type of EBS encryption to be used during replication.
        public let ebsEncryption: ReplicationConfigurationEbsEncryption
        /// The ARN of the EBS encryption key to be used during replication.
        public let ebsEncryptionKeyArn: String?
        /// The Point in time (PIT) policy to manage snapshots taken during replication.
        public let pitPolicy: [PITPolicyRule]
        /// The instance type to be used for the replication server.
        public let replicationServerInstanceType: String
        /// The security group IDs that will be used by the replication server.
        public let replicationServersSecurityGroupsIDs: [String]
        /// The subnet to be used by the replication staging area.
        public let stagingAreaSubnetId: String
        /// A set of tags to be associated with all resources created in the replication staging area: EC2 replication server, EBS volumes, EBS snapshots, etc.
        public let stagingAreaTags: [String: String]
        /// A set of tags to be associated with the Replication Configuration Template resource.
        public let tags: [String: String]?
        /// Whether to use a dedicated Replication Server in the replication staging area.
        public let useDedicatedReplicationServer: Bool

        public init(associateDefaultSecurityGroup: Bool, bandwidthThrottling: Int64 = 0, createPublicIP: Bool, dataPlaneRouting: ReplicationConfigurationDataPlaneRouting, defaultLargeStagingDiskType: ReplicationConfigurationDefaultLargeStagingDiskType, ebsEncryption: ReplicationConfigurationEbsEncryption, ebsEncryptionKeyArn: String? = nil, pitPolicy: [PITPolicyRule], replicationServerInstanceType: String, replicationServersSecurityGroupsIDs: [String], stagingAreaSubnetId: String, stagingAreaTags: [String: String], tags: [String: String]? = nil, useDedicatedReplicationServer: Bool) {
            self.associateDefaultSecurityGroup = associateDefaultSecurityGroup
            self.bandwidthThrottling = bandwidthThrottling
            self.createPublicIP = createPublicIP
            self.dataPlaneRouting = dataPlaneRouting
            self.defaultLargeStagingDiskType = defaultLargeStagingDiskType
            self.ebsEncryption = ebsEncryption
            self.ebsEncryptionKeyArn = ebsEncryptionKeyArn
            self.pitPolicy = pitPolicy
            self.replicationServerInstanceType = replicationServerInstanceType
            self.replicationServersSecurityGroupsIDs = replicationServersSecurityGroupsIDs
            self.stagingAreaSubnetId = stagingAreaSubnetId
            self.stagingAreaTags = stagingAreaTags
            self.tags = tags
            self.useDedicatedReplicationServer = useDedicatedReplicationServer
        }

        public func validate(name: String) throws {
            try self.validate(self.bandwidthThrottling, name: "bandwidthThrottling", parent: name, min: 0)
            try self.validate(self.ebsEncryptionKeyArn, name: "ebsEncryptionKeyArn", parent: name, max: 2048)
            try self.validate(self.ebsEncryptionKeyArn, name: "ebsEncryptionKeyArn", parent: name, min: 20)
            try self.validate(self.ebsEncryptionKeyArn, name: "ebsEncryptionKeyArn", parent: name, pattern: "^arn:.{16,2044}$")
            try self.pitPolicy.forEach {
                try $0.validate(name: "\(name).pitPolicy[]")
            }
            try self.validate(self.pitPolicy, name: "pitPolicy", parent: name, max: 10)
            try self.validate(self.pitPolicy, name: "pitPolicy", parent: name, min: 1)
            try self.validate(self.replicationServerInstanceType, name: "replicationServerInstanceType", parent: name, max: 255)
            try self.replicationServersSecurityGroupsIDs.forEach {
                try validate($0, name: "replicationServersSecurityGroupsIDs[]", parent: name, max: 255)
                try validate($0, name: "replicationServersSecurityGroupsIDs[]", parent: name, pattern: "^sg-[0-9a-fA-F]{8,}$")
            }
            try self.validate(self.replicationServersSecurityGroupsIDs, name: "replicationServersSecurityGroupsIDs", parent: name, max: 32)
            try self.validate(self.stagingAreaSubnetId, name: "stagingAreaSubnetId", parent: name, max: 255)
            try self.validate(self.stagingAreaSubnetId, name: "stagingAreaSubnetId", parent: name, pattern: "^subnet-[0-9a-fA-F]{8,}$")
            try self.stagingAreaTags.forEach {
                try validate($0.key, name: "stagingAreaTags.key", parent: name, max: 256)
                try validate($0.value, name: "stagingAreaTags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case associateDefaultSecurityGroup
            case bandwidthThrottling
            case createPublicIP
            case dataPlaneRouting
            case defaultLargeStagingDiskType
            case ebsEncryption
            case ebsEncryptionKeyArn
            case pitPolicy
            case replicationServerInstanceType
            case replicationServersSecurityGroupsIDs
            case stagingAreaSubnetId
            case stagingAreaTags
            case tags
            case useDedicatedReplicationServer
        }
    }

    public struct DataReplicationError: AWSDecodableShape {
        /// Error in data replication.
        public let error: DataReplicationErrorString?
        /// Error in data replication.
        public let rawError: String?

        public init(error: DataReplicationErrorString? = nil, rawError: String? = nil) {
            self.error = error
            self.rawError = rawError
        }

        private enum CodingKeys: String, CodingKey {
            case error
            case rawError
        }
    }

    public struct DataReplicationInfo: AWSDecodableShape {
        /// Error in data replication.
        public let dataReplicationError: DataReplicationError?
        /// Information about whether the data replication has been initiated.
        public let dataReplicationInitiation: DataReplicationInitiation?
        /// The state of the data replication.
        public let dataReplicationState: DataReplicationState?
        /// An estimate of when the data replication will be completed.
        public let etaDateTime: String?
        /// Data replication lag duration.
        public let lagDuration: String?
        /// The disks that should be replicated.
        public let replicatedDisks: [DataReplicationInfoReplicatedDisk]?

        public init(dataReplicationError: DataReplicationError? = nil, dataReplicationInitiation: DataReplicationInitiation? = nil, dataReplicationState: DataReplicationState? = nil, etaDateTime: String? = nil, lagDuration: String? = nil, replicatedDisks: [DataReplicationInfoReplicatedDisk]? = nil) {
            self.dataReplicationError = dataReplicationError
            self.dataReplicationInitiation = dataReplicationInitiation
            self.dataReplicationState = dataReplicationState
            self.etaDateTime = etaDateTime
            self.lagDuration = lagDuration
            self.replicatedDisks = replicatedDisks
        }

        private enum CodingKeys: String, CodingKey {
            case dataReplicationError
            case dataReplicationInitiation
            case dataReplicationState
            case etaDateTime
            case lagDuration
            case replicatedDisks
        }
    }

    public struct DataReplicationInfoReplicatedDisk: AWSDecodableShape {
        /// The size of the replication backlog in bytes.
        public let backloggedStorageBytes: Int64?
        /// The name of the device.
        public let deviceName: String?
        /// The amount of data replicated so far in bytes.
        public let replicatedStorageBytes: Int64?
        /// The amount of data to be rescanned in bytes.
        public let rescannedStorageBytes: Int64?
        /// The total amount of data to be replicated in bytes.
        public let totalStorageBytes: Int64?

        public init(backloggedStorageBytes: Int64? = nil, deviceName: String? = nil, replicatedStorageBytes: Int64? = nil, rescannedStorageBytes: Int64? = nil, totalStorageBytes: Int64? = nil) {
            self.backloggedStorageBytes = backloggedStorageBytes
            self.deviceName = deviceName
            self.replicatedStorageBytes = replicatedStorageBytes
            self.rescannedStorageBytes = rescannedStorageBytes
            self.totalStorageBytes = totalStorageBytes
        }

        private enum CodingKeys: String, CodingKey {
            case backloggedStorageBytes
            case deviceName
            case replicatedStorageBytes
            case rescannedStorageBytes
            case totalStorageBytes
        }
    }

    public struct DataReplicationInitiation: AWSDecodableShape {
        /// The date and time of the next attempt to initiate data replication.
        public let nextAttemptDateTime: String?
        /// The date and time of the current attempt to initiate data replication.
        public let startDateTime: String?
        /// The steps of the current attempt to initiate data replication.
        public let steps: [DataReplicationInitiationStep]?

        public init(nextAttemptDateTime: String? = nil, startDateTime: String? = nil, steps: [DataReplicationInitiationStep]? = nil) {
            self.nextAttemptDateTime = nextAttemptDateTime
            self.startDateTime = startDateTime
            self.steps = steps
        }

        private enum CodingKeys: String, CodingKey {
            case nextAttemptDateTime
            case startDateTime
            case steps
        }
    }

    public struct DataReplicationInitiationStep: AWSDecodableShape {
        /// The name of the step.
        public let name: DataReplicationInitiationStepName?
        /// The status of the step.
        public let status: DataReplicationInitiationStepStatus?

        public init(name: DataReplicationInitiationStepName? = nil, status: DataReplicationInitiationStepStatus? = nil) {
            self.name = name
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case name
            case status
        }
    }

    public struct DeleteJobRequest: AWSEncodableShape {
        /// The ID of the Job to be deleted.
        public let jobID: String

        public init(jobID: String) {
            self.jobID = jobID
        }

        public func validate(name: String) throws {
            try self.validate(self.jobID, name: "jobID", parent: name, max: 24)
            try self.validate(self.jobID, name: "jobID", parent: name, min: 24)
            try self.validate(self.jobID, name: "jobID", parent: name, pattern: "^drsjob-[0-9a-zA-Z]{17}$")
        }

        private enum CodingKeys: String, CodingKey {
            case jobID
        }
    }

    public struct DeleteJobResponse: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteRecoveryInstanceRequest: AWSEncodableShape {
        /// The ID of the Recovery Instance to be deleted.
        public let recoveryInstanceID: String

        public init(recoveryInstanceID: String) {
            self.recoveryInstanceID = recoveryInstanceID
        }

        public func validate(name: String) throws {
            try self.validate(self.recoveryInstanceID, name: "recoveryInstanceID", parent: name, max: 19)
            try self.validate(self.recoveryInstanceID, name: "recoveryInstanceID", parent: name, min: 10)
            try self.validate(self.recoveryInstanceID, name: "recoveryInstanceID", parent: name, pattern: "^i-[0-9a-fA-F]{8,}$")
        }

        private enum CodingKeys: String, CodingKey {
            case recoveryInstanceID
        }
    }

    public struct DeleteReplicationConfigurationTemplateRequest: AWSEncodableShape {
        /// The ID of the Replication Configuration Template to be deleted.
        public let replicationConfigurationTemplateID: String

        public init(replicationConfigurationTemplateID: String) {
            self.replicationConfigurationTemplateID = replicationConfigurationTemplateID
        }

        public func validate(name: String) throws {
            try self.validate(self.replicationConfigurationTemplateID, name: "replicationConfigurationTemplateID", parent: name, max: 21)
            try self.validate(self.replicationConfigurationTemplateID, name: "replicationConfigurationTemplateID", parent: name, min: 21)
            try self.validate(self.replicationConfigurationTemplateID, name: "replicationConfigurationTemplateID", parent: name, pattern: "^rct-[0-9a-zA-Z]{17}$")
        }

        private enum CodingKeys: String, CodingKey {
            case replicationConfigurationTemplateID
        }
    }

    public struct DeleteReplicationConfigurationTemplateResponse: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteSourceServerRequest: AWSEncodableShape {
        /// The ID of the Source Server to be deleted.
        public let sourceServerID: String

        public init(sourceServerID: String) {
            self.sourceServerID = sourceServerID
        }

        public func validate(name: String) throws {
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, max: 19)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, min: 19)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, pattern: "^s-[0-9a-zA-Z]{17}$")
        }

        private enum CodingKeys: String, CodingKey {
            case sourceServerID
        }
    }

    public struct DeleteSourceServerResponse: AWSDecodableShape {
        public init() {}
    }

    public struct DescribeJobLogItemsRequest: AWSEncodableShape {
        /// The ID of the Job for which Job log items will be retrieved.
        public let jobID: String
        /// Maximum number of Job log items to retrieve.
        public let maxResults: Int?
        /// The token of the next Job log items to retrieve.
        public let nextToken: String?

        public init(jobID: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.jobID = jobID
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.jobID, name: "jobID", parent: name, max: 24)
            try self.validate(self.jobID, name: "jobID", parent: name, min: 24)
            try self.validate(self.jobID, name: "jobID", parent: name, pattern: "^drsjob-[0-9a-zA-Z]{17}$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
        }

        private enum CodingKeys: String, CodingKey {
            case jobID
            case maxResults
            case nextToken
        }
    }

    public struct DescribeJobLogItemsResponse: AWSDecodableShape {
        /// An array of Job log items.
        public let items: [JobLog]?
        /// The token of the next Job log items to retrieve.
        public let nextToken: String?

        public init(items: [JobLog]? = nil, nextToken: String? = nil) {
            self.items = items
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case items
            case nextToken
        }
    }

    public struct DescribeJobsRequest: AWSEncodableShape {
        /// A set of filters by which to return Jobs.
        public let filters: DescribeJobsRequestFilters?
        /// Maximum number of Jobs to retrieve.
        public let maxResults: Int?
        /// The token of the next Job to retrieve.
        public let nextToken: String?

        public init(filters: DescribeJobsRequestFilters? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.filters = filters
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.filters?.validate(name: "\(name).filters")
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
        }

        private enum CodingKeys: String, CodingKey {
            case filters
            case maxResults
            case nextToken
        }
    }

    public struct DescribeJobsRequestFilters: AWSEncodableShape {
        /// The start date in a date range query.
        public let fromDate: String?
        /// An array of Job IDs that should be returned. An empty array means all jobs.
        public let jobIDs: [String]?
        /// The end date in a date range query.
        public let toDate: String?

        public init(fromDate: String? = nil, jobIDs: [String]? = nil, toDate: String? = nil) {
            self.fromDate = fromDate
            self.jobIDs = jobIDs
            self.toDate = toDate
        }

        public func validate(name: String) throws {
            try self.validate(self.fromDate, name: "fromDate", parent: name, max: 32)
            try self.validate(self.fromDate, name: "fromDate", parent: name, min: 19)
            try self.validate(self.fromDate, name: "fromDate", parent: name, pattern: "^[1-9][0-9]*-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([0-1][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\\.[0-9]+)?Z$")
            try self.jobIDs?.forEach {
                try validate($0, name: "jobIDs[]", parent: name, max: 24)
                try validate($0, name: "jobIDs[]", parent: name, min: 24)
                try validate($0, name: "jobIDs[]", parent: name, pattern: "^drsjob-[0-9a-zA-Z]{17}$")
            }
            try self.validate(self.jobIDs, name: "jobIDs", parent: name, max: 1000)
            try self.validate(self.toDate, name: "toDate", parent: name, max: 32)
            try self.validate(self.toDate, name: "toDate", parent: name, min: 19)
            try self.validate(self.toDate, name: "toDate", parent: name, pattern: "^[1-9][0-9]*-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([0-1][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\\.[0-9]+)?Z$")
        }

        private enum CodingKeys: String, CodingKey {
            case fromDate
            case jobIDs
            case toDate
        }
    }

    public struct DescribeJobsResponse: AWSDecodableShape {
        /// An array of Jobs.
        public let items: [Job]?
        /// The token of the next Job to retrieve.
        public let nextToken: String?

        public init(items: [Job]? = nil, nextToken: String? = nil) {
            self.items = items
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case items
            case nextToken
        }
    }

    public struct DescribeRecoveryInstancesRequest: AWSEncodableShape {
        /// A set of filters by which to return Recovery Instances.
        public let filters: DescribeRecoveryInstancesRequestFilters?
        /// Maximum number of Recovery Instances to retrieve.
        public let maxResults: Int?
        /// The token of the next Recovery Instance to retrieve.
        public let nextToken: String?

        public init(filters: DescribeRecoveryInstancesRequestFilters? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.filters = filters
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.filters?.validate(name: "\(name).filters")
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
        }

        private enum CodingKeys: String, CodingKey {
            case filters
            case maxResults
            case nextToken
        }
    }

    public struct DescribeRecoveryInstancesRequestFilters: AWSEncodableShape {
        /// An array of Recovery Instance IDs that should be returned. An empty array means all Recovery Instances.
        public let recoveryInstanceIDs: [String]?
        /// An array of Source Server IDs for which associated Recovery Instances should be returned.
        public let sourceServerIDs: [String]?

        public init(recoveryInstanceIDs: [String]? = nil, sourceServerIDs: [String]? = nil) {
            self.recoveryInstanceIDs = recoveryInstanceIDs
            self.sourceServerIDs = sourceServerIDs
        }

        public func validate(name: String) throws {
            try self.recoveryInstanceIDs?.forEach {
                try validate($0, name: "recoveryInstanceIDs[]", parent: name, max: 19)
                try validate($0, name: "recoveryInstanceIDs[]", parent: name, min: 10)
                try validate($0, name: "recoveryInstanceIDs[]", parent: name, pattern: "^i-[0-9a-fA-F]{8,}$")
            }
            try self.validate(self.recoveryInstanceIDs, name: "recoveryInstanceIDs", parent: name, max: 200)
            try self.sourceServerIDs?.forEach {
                try validate($0, name: "sourceServerIDs[]", parent: name, max: 19)
                try validate($0, name: "sourceServerIDs[]", parent: name, min: 19)
                try validate($0, name: "sourceServerIDs[]", parent: name, pattern: "^s-[0-9a-zA-Z]{17}$")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case recoveryInstanceIDs
            case sourceServerIDs
        }
    }

    public struct DescribeRecoveryInstancesResponse: AWSDecodableShape {
        /// An array of Recovery Instances.
        public let items: [RecoveryInstance]?
        /// The token of the next Recovery Instance to retrieve.
        public let nextToken: String?

        public init(items: [RecoveryInstance]? = nil, nextToken: String? = nil) {
            self.items = items
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case items
            case nextToken
        }
    }

    public struct DescribeRecoverySnapshotsRequest: AWSEncodableShape {
        /// A set of filters by which to return Recovery Snapshots.
        public let filters: DescribeRecoverySnapshotsRequestFilters?
        /// Maximum number of Recovery Snapshots to retrieve.
        public let maxResults: Int?
        /// The token of the next Recovery Snapshot to retrieve.
        public let nextToken: String?
        /// The sorted ordering by which to return Recovery Snapshots.
        public let order: RecoverySnapshotsOrder?
        /// Filter Recovery Snapshots by Source Server ID.
        public let sourceServerID: String

        public init(filters: DescribeRecoverySnapshotsRequestFilters? = nil, maxResults: Int? = nil, nextToken: String? = nil, order: RecoverySnapshotsOrder? = nil, sourceServerID: String) {
            self.filters = filters
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.order = order
            self.sourceServerID = sourceServerID
        }

        public func validate(name: String) throws {
            try self.filters?.validate(name: "\(name).filters")
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, max: 19)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, min: 19)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, pattern: "^s-[0-9a-zA-Z]{17}$")
        }

        private enum CodingKeys: String, CodingKey {
            case filters
            case maxResults
            case nextToken
            case order
            case sourceServerID
        }
    }

    public struct DescribeRecoverySnapshotsRequestFilters: AWSEncodableShape {
        /// The start date in a date range query.
        public let fromDateTime: String?
        /// The end date in a date range query.
        public let toDateTime: String?

        public init(fromDateTime: String? = nil, toDateTime: String? = nil) {
            self.fromDateTime = fromDateTime
            self.toDateTime = toDateTime
        }

        public func validate(name: String) throws {
            try self.validate(self.fromDateTime, name: "fromDateTime", parent: name, max: 32)
            try self.validate(self.fromDateTime, name: "fromDateTime", parent: name, min: 19)
            try self.validate(self.fromDateTime, name: "fromDateTime", parent: name, pattern: "^[1-9][0-9]*-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([0-1][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\\.[0-9]+)?Z$")
            try self.validate(self.toDateTime, name: "toDateTime", parent: name, max: 32)
            try self.validate(self.toDateTime, name: "toDateTime", parent: name, min: 19)
            try self.validate(self.toDateTime, name: "toDateTime", parent: name, pattern: "^[1-9][0-9]*-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([0-1][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\\.[0-9]+)?Z$")
        }

        private enum CodingKeys: String, CodingKey {
            case fromDateTime
            case toDateTime
        }
    }

    public struct DescribeRecoverySnapshotsResponse: AWSDecodableShape {
        /// An array of Recovery Snapshots.
        public let items: [RecoverySnapshot]?
        /// The token of the next Recovery Snapshot to retrieve.
        public let nextToken: String?

        public init(items: [RecoverySnapshot]? = nil, nextToken: String? = nil) {
            self.items = items
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case items
            case nextToken
        }
    }

    public struct DescribeReplicationConfigurationTemplatesRequest: AWSEncodableShape {
        /// Maximum number of Replication Configuration Templates to retrieve.
        public let maxResults: Int?
        /// The token of the next Replication Configuration Template to retrieve.
        public let nextToken: String?
        /// The IDs of the Replication Configuration Templates to retrieve. An empty list means all Replication Configuration Templates.
        public let replicationConfigurationTemplateIDs: [String]?

        public init(maxResults: Int? = nil, nextToken: String? = nil, replicationConfigurationTemplateIDs: [String]? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.replicationConfigurationTemplateIDs = replicationConfigurationTemplateIDs
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
            try self.replicationConfigurationTemplateIDs?.forEach {
                try validate($0, name: "replicationConfigurationTemplateIDs[]", parent: name, max: 21)
                try validate($0, name: "replicationConfigurationTemplateIDs[]", parent: name, min: 21)
                try validate($0, name: "replicationConfigurationTemplateIDs[]", parent: name, pattern: "^rct-[0-9a-zA-Z]{17}$")
            }
            try self.validate(self.replicationConfigurationTemplateIDs, name: "replicationConfigurationTemplateIDs", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults
            case nextToken
            case replicationConfigurationTemplateIDs
        }
    }

    public struct DescribeReplicationConfigurationTemplatesResponse: AWSDecodableShape {
        /// An array of Replication Configuration Templates.
        public let items: [ReplicationConfigurationTemplate]?
        /// The token of the next Replication Configuration Template to retrieve.
        public let nextToken: String?

        public init(items: [ReplicationConfigurationTemplate]? = nil, nextToken: String? = nil) {
            self.items = items
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case items
            case nextToken
        }
    }

    public struct DescribeSourceServersRequest: AWSEncodableShape {
        /// A set of filters by which to return Source Servers.
        public let filters: DescribeSourceServersRequestFilters?
        /// Maximum number of Source Servers to retrieve.
        public let maxResults: Int?
        /// The token of the next Source Server to retrieve.
        public let nextToken: String?

        public init(filters: DescribeSourceServersRequestFilters? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.filters = filters
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.filters?.validate(name: "\(name).filters")
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
        }

        private enum CodingKeys: String, CodingKey {
            case filters
            case maxResults
            case nextToken
        }
    }

    public struct DescribeSourceServersRequestFilters: AWSEncodableShape {
        /// An ID that describes the hardware of the Source Server. This is either an EC2 instance id, a VMware uuid or a mac address.
        public let hardwareId: String?
        /// An array of Source Servers IDs that should be returned. An empty array means all Source Servers.
        public let sourceServerIDs: [String]?
        /// An array of staging account IDs that extended source servers belong to. An empty array means all source servers will be shown.
        public let stagingAccountIDs: [String]?

        public init(hardwareId: String? = nil, sourceServerIDs: [String]? = nil, stagingAccountIDs: [String]? = nil) {
            self.hardwareId = hardwareId
            self.sourceServerIDs = sourceServerIDs
            self.stagingAccountIDs = stagingAccountIDs
        }

        public func validate(name: String) throws {
            try self.validate(self.hardwareId, name: "hardwareId", parent: name, max: 256)
            try self.sourceServerIDs?.forEach {
                try validate($0, name: "sourceServerIDs[]", parent: name, max: 19)
                try validate($0, name: "sourceServerIDs[]", parent: name, min: 19)
                try validate($0, name: "sourceServerIDs[]", parent: name, pattern: "^s-[0-9a-zA-Z]{17}$")
            }
            try self.validate(self.sourceServerIDs, name: "sourceServerIDs", parent: name, max: 200)
            try self.stagingAccountIDs?.forEach {
                try validate($0, name: "stagingAccountIDs[]", parent: name, max: 12)
                try validate($0, name: "stagingAccountIDs[]", parent: name, min: 12)
                try validate($0, name: "stagingAccountIDs[]", parent: name, pattern: "[0-9]{12,}")
            }
            try self.validate(self.stagingAccountIDs, name: "stagingAccountIDs", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case hardwareId
            case sourceServerIDs
            case stagingAccountIDs
        }
    }

    public struct DescribeSourceServersResponse: AWSDecodableShape {
        /// An array of Source Servers.
        public let items: [SourceServer]?
        /// The token of the next Source Server to retrieve.
        public let nextToken: String?

        public init(items: [SourceServer]? = nil, nextToken: String? = nil) {
            self.items = items
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case items
            case nextToken
        }
    }

    public struct DisconnectRecoveryInstanceRequest: AWSEncodableShape {
        /// The ID of the Recovery Instance to disconnect.
        public let recoveryInstanceID: String

        public init(recoveryInstanceID: String) {
            self.recoveryInstanceID = recoveryInstanceID
        }

        public func validate(name: String) throws {
            try self.validate(self.recoveryInstanceID, name: "recoveryInstanceID", parent: name, max: 19)
            try self.validate(self.recoveryInstanceID, name: "recoveryInstanceID", parent: name, min: 10)
            try self.validate(self.recoveryInstanceID, name: "recoveryInstanceID", parent: name, pattern: "^i-[0-9a-fA-F]{8,}$")
        }

        private enum CodingKeys: String, CodingKey {
            case recoveryInstanceID
        }
    }

    public struct DisconnectSourceServerRequest: AWSEncodableShape {
        /// The ID of the Source Server to disconnect.
        public let sourceServerID: String

        public init(sourceServerID: String) {
            self.sourceServerID = sourceServerID
        }

        public func validate(name: String) throws {
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, max: 19)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, min: 19)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, pattern: "^s-[0-9a-zA-Z]{17}$")
        }

        private enum CodingKeys: String, CodingKey {
            case sourceServerID
        }
    }

    public struct Disk: AWSDecodableShape {
        /// The amount of storage on the disk in bytes.
        public let bytes: Int64?
        /// The disk or device name.
        public let deviceName: String?

        public init(bytes: Int64? = nil, deviceName: String? = nil) {
            self.bytes = bytes
            self.deviceName = deviceName
        }

        private enum CodingKeys: String, CodingKey {
            case bytes
            case deviceName
        }
    }

    public struct GetFailbackReplicationConfigurationRequest: AWSEncodableShape {
        /// The ID of the Recovery Instance whose failback replication configuration should be returned.
        public let recoveryInstanceID: String

        public init(recoveryInstanceID: String) {
            self.recoveryInstanceID = recoveryInstanceID
        }

        public func validate(name: String) throws {
            try self.validate(self.recoveryInstanceID, name: "recoveryInstanceID", parent: name, max: 19)
            try self.validate(self.recoveryInstanceID, name: "recoveryInstanceID", parent: name, min: 10)
            try self.validate(self.recoveryInstanceID, name: "recoveryInstanceID", parent: name, pattern: "^i-[0-9a-fA-F]{8,}$")
        }

        private enum CodingKeys: String, CodingKey {
            case recoveryInstanceID
        }
    }

    public struct GetFailbackReplicationConfigurationResponse: AWSDecodableShape {
        /// Configure bandwidth throttling for the outbound data transfer rate of the Recovery Instance in Mbps.
        public let bandwidthThrottling: Int64?
        /// The name of the Failback Replication Configuration.
        public let name: String?
        /// The ID of the Recovery Instance.
        public let recoveryInstanceID: String
        /// Whether to use Private IP for the failback replication of the Recovery Instance.
        public let usePrivateIP: Bool?

        public init(bandwidthThrottling: Int64? = nil, name: String? = nil, recoveryInstanceID: String, usePrivateIP: Bool? = nil) {
            self.bandwidthThrottling = bandwidthThrottling
            self.name = name
            self.recoveryInstanceID = recoveryInstanceID
            self.usePrivateIP = usePrivateIP
        }

        private enum CodingKeys: String, CodingKey {
            case bandwidthThrottling
            case name
            case recoveryInstanceID
            case usePrivateIP
        }
    }

    public struct GetLaunchConfigurationRequest: AWSEncodableShape {
        /// The ID of the Source Server that we want to retrieve a Launch Configuration for.
        public let sourceServerID: String

        public init(sourceServerID: String) {
            self.sourceServerID = sourceServerID
        }

        public func validate(name: String) throws {
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, max: 19)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, min: 19)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, pattern: "^s-[0-9a-zA-Z]{17}$")
        }

        private enum CodingKeys: String, CodingKey {
            case sourceServerID
        }
    }

    public struct GetReplicationConfigurationRequest: AWSEncodableShape {
        /// The ID of the Source Serve for this Replication Configuration.r
        public let sourceServerID: String

        public init(sourceServerID: String) {
            self.sourceServerID = sourceServerID
        }

        public func validate(name: String) throws {
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, max: 19)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, min: 19)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, pattern: "^s-[0-9a-zA-Z]{17}$")
        }

        private enum CodingKeys: String, CodingKey {
            case sourceServerID
        }
    }

    public struct IdentificationHints: AWSDecodableShape {
        /// AWS Instance ID identification hint.
        public let awsInstanceID: String?
        /// Fully Qualified Domain Name identification hint.
        public let fqdn: String?
        /// Hostname identification hint.
        public let hostname: String?
        /// vCenter VM path identification hint.
        public let vmWareUuid: String?

        public init(awsInstanceID: String? = nil, fqdn: String? = nil, hostname: String? = nil, vmWareUuid: String? = nil) {
            self.awsInstanceID = awsInstanceID
            self.fqdn = fqdn
            self.hostname = hostname
            self.vmWareUuid = vmWareUuid
        }

        private enum CodingKeys: String, CodingKey {
            case awsInstanceID
            case fqdn
            case hostname
            case vmWareUuid
        }
    }

    public struct InitializeServiceRequest: AWSEncodableShape {
        public init() {}
    }

    public struct InitializeServiceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct Job: AWSDecodableShape {
        /// The ARN of a Job.
        public let arn: String?
        /// The date and time of when the Job was created.
        public let creationDateTime: String?
        /// The date and time of when the Job ended.
        public let endDateTime: String?
        /// A string representing who initiated the Job.
        public let initiatedBy: InitiatedBy?
        /// The ID of the Job.
        public let jobID: String
        /// A list of servers that the Job is acting upon.
        public let participatingServers: [ParticipatingServer]?
        /// The status of the Job.
        public let status: JobStatus?
        /// A list of tags associated with the Job.
        public let tags: [String: String]?
        /// The type of the Job.
        public let type: JobType?

        public init(arn: String? = nil, creationDateTime: String? = nil, endDateTime: String? = nil, initiatedBy: InitiatedBy? = nil, jobID: String, participatingServers: [ParticipatingServer]? = nil, status: JobStatus? = nil, tags: [String: String]? = nil, type: JobType? = nil) {
            self.arn = arn
            self.creationDateTime = creationDateTime
            self.endDateTime = endDateTime
            self.initiatedBy = initiatedBy
            self.jobID = jobID
            self.participatingServers = participatingServers
            self.status = status
            self.tags = tags
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case creationDateTime
            case endDateTime
            case initiatedBy
            case jobID
            case participatingServers
            case status
            case tags
            case type
        }
    }

    public struct JobLog: AWSDecodableShape {
        /// The event represents the type of a log.
        public let event: JobLogEvent?
        /// Metadata associated with a Job log.
        public let eventData: JobLogEventData?
        /// The date and time the log was taken.
        public let logDateTime: String?

        public init(event: JobLogEvent? = nil, eventData: JobLogEventData? = nil, logDateTime: String? = nil) {
            self.event = event
            self.eventData = eventData
            self.logDateTime = logDateTime
        }

        private enum CodingKeys: String, CodingKey {
            case event
            case eventData
            case logDateTime
        }
    }

    public struct JobLogEventData: AWSDecodableShape {
        /// Properties of a conversion job
        public let conversionProperties: ConversionProperties?
        /// The ID of a conversion server.
        public let conversionServerID: String?
        /// A string representing a job error.
        public let rawError: String?
        /// The ID of a Source Server.
        public let sourceServerID: String?
        /// The ID of a Recovery Instance.
        public let targetInstanceID: String?

        public init(conversionProperties: ConversionProperties? = nil, conversionServerID: String? = nil, rawError: String? = nil, sourceServerID: String? = nil, targetInstanceID: String? = nil) {
            self.conversionProperties = conversionProperties
            self.conversionServerID = conversionServerID
            self.rawError = rawError
            self.sourceServerID = sourceServerID
            self.targetInstanceID = targetInstanceID
        }

        private enum CodingKeys: String, CodingKey {
            case conversionProperties
            case conversionServerID
            case rawError
            case sourceServerID
            case targetInstanceID
        }
    }

    public struct LaunchConfiguration: AWSDecodableShape {
        /// Whether we should copy the Private IP of the Source Server to the Recovery Instance.
        public let copyPrivateIp: Bool?
        /// Whether we want to copy the tags of the Source Server to the EC2 machine of the Recovery Instance.
        public let copyTags: Bool?
        /// The EC2 launch template ID of this launch configuration.
        public let ec2LaunchTemplateID: String?
        /// The state of the Recovery Instance in EC2 after the recovery operation.
        public let launchDisposition: LaunchDisposition?
        /// The licensing configuration to be used for this launch configuration.
        public let licensing: Licensing?
        /// The name of the launch configuration.
        public let name: String?
        /// The ID of the Source Server for this launch configuration.
        public let sourceServerID: String?
        /// Whether Elastic Disaster Recovery should try to automatically choose the instance type that best matches the OS, CPU, and RAM of your Source Server.
        public let targetInstanceTypeRightSizingMethod: TargetInstanceTypeRightSizingMethod?

        public init(copyPrivateIp: Bool? = nil, copyTags: Bool? = nil, ec2LaunchTemplateID: String? = nil, launchDisposition: LaunchDisposition? = nil, licensing: Licensing? = nil, name: String? = nil, sourceServerID: String? = nil, targetInstanceTypeRightSizingMethod: TargetInstanceTypeRightSizingMethod? = nil) {
            self.copyPrivateIp = copyPrivateIp
            self.copyTags = copyTags
            self.ec2LaunchTemplateID = ec2LaunchTemplateID
            self.launchDisposition = launchDisposition
            self.licensing = licensing
            self.name = name
            self.sourceServerID = sourceServerID
            self.targetInstanceTypeRightSizingMethod = targetInstanceTypeRightSizingMethod
        }

        private enum CodingKeys: String, CodingKey {
            case copyPrivateIp
            case copyTags
            case ec2LaunchTemplateID
            case launchDisposition
            case licensing
            case name
            case sourceServerID
            case targetInstanceTypeRightSizingMethod
        }
    }

    public struct Licensing: AWSEncodableShape & AWSDecodableShape {
        /// Whether to enable "Bring your own license" or not.
        public let osByol: Bool?

        public init(osByol: Bool? = nil) {
            self.osByol = osByol
        }

        private enum CodingKeys: String, CodingKey {
            case osByol
        }
    }

    public struct LifeCycle: AWSDecodableShape {
        /// The date and time of when the Source Server was added to the service.
        public let addedToServiceDateTime: String?
        /// The amount of time that the Source Server has been replicating for.
        public let elapsedReplicationDuration: String?
        /// The date and time of the first byte that was replicated from the Source Server.
        public let firstByteDateTime: String?
        /// An object containing information regarding the last launch of the Source Server.
        public let lastLaunch: LifeCycleLastLaunch?
        /// The date and time this Source Server was last seen by the service.
        public let lastSeenByServiceDateTime: String?

        public init(addedToServiceDateTime: String? = nil, elapsedReplicationDuration: String? = nil, firstByteDateTime: String? = nil, lastLaunch: LifeCycleLastLaunch? = nil, lastSeenByServiceDateTime: String? = nil) {
            self.addedToServiceDateTime = addedToServiceDateTime
            self.elapsedReplicationDuration = elapsedReplicationDuration
            self.firstByteDateTime = firstByteDateTime
            self.lastLaunch = lastLaunch
            self.lastSeenByServiceDateTime = lastSeenByServiceDateTime
        }

        private enum CodingKeys: String, CodingKey {
            case addedToServiceDateTime
            case elapsedReplicationDuration
            case firstByteDateTime
            case lastLaunch
            case lastSeenByServiceDateTime
        }
    }

    public struct LifeCycleLastLaunch: AWSDecodableShape {
        /// An object containing information regarding the initiation of the last launch of a Source Server.
        public let initiated: LifeCycleLastLaunchInitiated?

        public init(initiated: LifeCycleLastLaunchInitiated? = nil) {
            self.initiated = initiated
        }

        private enum CodingKeys: String, CodingKey {
            case initiated
        }
    }

    public struct LifeCycleLastLaunchInitiated: AWSDecodableShape {
        /// The date and time the last Source Server launch was initiated.
        public let apiCallDateTime: String?
        /// The ID of the Job that was used to last launch the Source Server.
        public let jobID: String?
        /// The Job type that was used to last launch the Source Server.
        public let type: LastLaunchType?

        public init(apiCallDateTime: String? = nil, jobID: String? = nil, type: LastLaunchType? = nil) {
            self.apiCallDateTime = apiCallDateTime
            self.jobID = jobID
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case apiCallDateTime
            case jobID
            case type
        }
    }

    public struct ListExtensibleSourceServersRequest: AWSEncodableShape {
        /// The maximum number of extensible source servers to retrieve.
        public let maxResults: Int?
        /// The token of the next extensible source server to retrieve.
        public let nextToken: String?
        /// The Id of the staging Account to retrieve extensible source servers from.
        public let stagingAccountID: String

        public init(maxResults: Int? = nil, nextToken: String? = nil, stagingAccountID: String) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.stagingAccountID = stagingAccountID
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 300)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
            try self.validate(self.stagingAccountID, name: "stagingAccountID", parent: name, max: 12)
            try self.validate(self.stagingAccountID, name: "stagingAccountID", parent: name, min: 12)
            try self.validate(self.stagingAccountID, name: "stagingAccountID", parent: name, pattern: "[0-9]{12,}")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults
            case nextToken
            case stagingAccountID
        }
    }

    public struct ListExtensibleSourceServersResponse: AWSDecodableShape {
        /// A list of source servers on a staging Account that are extensible.
        public let items: [StagingSourceServer]?
        /// The token of the next extensible source server to retrieve.
        public let nextToken: String?

        public init(items: [StagingSourceServer]? = nil, nextToken: String? = nil) {
            self.items = items
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case items
            case nextToken
        }
    }

    public struct ListStagingAccountsRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "maxResults", location: .querystring("maxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("nextToken"))
        ]

        /// The maximum number of staging Accounts to retrieve.
        public let maxResults: Int?
        /// The token of the next staging Account to retrieve.
        public let nextToken: String?

        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListStagingAccountsResponse: AWSDecodableShape {
        /// An array of staging AWS Accounts.
        public let accounts: [Account]?
        /// The token of the next staging Account to retrieve.
        public let nextToken: String?

        public init(accounts: [Account]? = nil, nextToken: String? = nil) {
            self.accounts = accounts
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case accounts
            case nextToken
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("resourceArn"))
        ]

        /// The ARN of the resource whose tags should be returned.
        public let resourceArn: String

        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 2048)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 20)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:.{16,2044}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        /// The tags of the requested resource.
        public let tags: [String: String]?

        public init(tags: [String: String]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags
        }
    }

    public struct NetworkInterface: AWSDecodableShape {
        /// Network interface IPs.
        public let ips: [String]?
        /// Whether this is the primary network interface.
        public let isPrimary: Bool?
        /// The MAC address of the network interface.
        public let macAddress: String?

        public init(ips: [String]? = nil, isPrimary: Bool? = nil, macAddress: String? = nil) {
            self.ips = ips
            self.isPrimary = isPrimary
            self.macAddress = macAddress
        }

        private enum CodingKeys: String, CodingKey {
            case ips
            case isPrimary
            case macAddress
        }
    }

    public struct OS: AWSDecodableShape {
        /// The long name of the Operating System.
        public let fullString: String?

        public init(fullString: String? = nil) {
            self.fullString = fullString
        }

        private enum CodingKeys: String, CodingKey {
            case fullString
        }
    }

    public struct PITPolicyRule: AWSEncodableShape & AWSDecodableShape {
        /// Whether this rule is enabled or not.
        public let enabled: Bool?
        /// How often, in the chosen units, a snapshot should be taken.
        public let interval: Int
        /// The duration to retain a snapshot for, in the chosen units.
        public let retentionDuration: Int
        /// The ID of the rule.
        public let ruleID: Int64?
        /// The units used to measure the interval and retentionDuration.
        public let units: PITPolicyRuleUnits

        public init(enabled: Bool? = nil, interval: Int, retentionDuration: Int, ruleID: Int64? = nil, units: PITPolicyRuleUnits) {
            self.enabled = enabled
            self.interval = interval
            self.retentionDuration = retentionDuration
            self.ruleID = ruleID
            self.units = units
        }

        public func validate(name: String) throws {
            try self.validate(self.interval, name: "interval", parent: name, min: 1)
            try self.validate(self.retentionDuration, name: "retentionDuration", parent: name, min: 1)
            try self.validate(self.ruleID, name: "ruleID", parent: name, min: 0)
        }

        private enum CodingKeys: String, CodingKey {
            case enabled
            case interval
            case retentionDuration
            case ruleID
            case units
        }
    }

    public struct ParticipatingServer: AWSDecodableShape {
        /// The launch status of a participating server.
        public let launchStatus: LaunchStatus?
        /// The Recovery Instance ID of a participating server.
        public let recoveryInstanceID: String?
        /// The Source Server ID of a participating server.
        public let sourceServerID: String?

        public init(launchStatus: LaunchStatus? = nil, recoveryInstanceID: String? = nil, sourceServerID: String? = nil) {
            self.launchStatus = launchStatus
            self.recoveryInstanceID = recoveryInstanceID
            self.sourceServerID = sourceServerID
        }

        private enum CodingKeys: String, CodingKey {
            case launchStatus
            case recoveryInstanceID
            case sourceServerID
        }
    }

    public struct RecoveryInstance: AWSDecodableShape {
        /// The ARN of the Recovery Instance.
        public let arn: String?
        /// The Data Replication Info of the Recovery Instance.
        public let dataReplicationInfo: RecoveryInstanceDataReplicationInfo?
        /// The EC2 instance ID of the Recovery Instance.
        public let ec2InstanceID: String?
        /// The state of the EC2 instance for this Recovery Instance.
        public let ec2InstanceState: EC2InstanceState?
        /// An object representing failback related information of the Recovery Instance.
        public let failback: RecoveryInstanceFailback?
        /// Whether this Recovery Instance was created for a drill or for an actual Recovery event.
        public let isDrill: Bool?
        /// The ID of the Job that created the Recovery Instance.
        public let jobID: String?
        /// Environment (On Premises / AWS) of the instance that the recovery instance originated from.
        public let originEnvironment: OriginEnvironment?
        /// The date and time of the Point in Time (PIT) snapshot that this Recovery Instance was launched from.
        public let pointInTimeSnapshotDateTime: String?
        /// The ID of the Recovery Instance.
        public let recoveryInstanceID: String?
        /// Properties of the Recovery Instance machine.
        public let recoveryInstanceProperties: RecoveryInstanceProperties?
        /// The Source Server ID that this Recovery Instance is associated with.
        public let sourceServerID: String?
        /// An array of tags that are associated with the Recovery Instance.
        public let tags: [String: String]?

        public init(arn: String? = nil, dataReplicationInfo: RecoveryInstanceDataReplicationInfo? = nil, ec2InstanceID: String? = nil, ec2InstanceState: EC2InstanceState? = nil, failback: RecoveryInstanceFailback? = nil, isDrill: Bool? = nil, jobID: String? = nil, originEnvironment: OriginEnvironment? = nil, pointInTimeSnapshotDateTime: String? = nil, recoveryInstanceID: String? = nil, recoveryInstanceProperties: RecoveryInstanceProperties? = nil, sourceServerID: String? = nil, tags: [String: String]? = nil) {
            self.arn = arn
            self.dataReplicationInfo = dataReplicationInfo
            self.ec2InstanceID = ec2InstanceID
            self.ec2InstanceState = ec2InstanceState
            self.failback = failback
            self.isDrill = isDrill
            self.jobID = jobID
            self.originEnvironment = originEnvironment
            self.pointInTimeSnapshotDateTime = pointInTimeSnapshotDateTime
            self.recoveryInstanceID = recoveryInstanceID
            self.recoveryInstanceProperties = recoveryInstanceProperties
            self.sourceServerID = sourceServerID
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case dataReplicationInfo
            case ec2InstanceID
            case ec2InstanceState
            case failback
            case isDrill
            case jobID
            case originEnvironment
            case pointInTimeSnapshotDateTime
            case recoveryInstanceID
            case recoveryInstanceProperties
            case sourceServerID
            case tags
        }
    }

    public struct RecoveryInstanceDataReplicationError: AWSDecodableShape {
        /// Error in data replication.
        public let error: FailbackReplicationError?
        /// Error in data replication.
        public let rawError: String?

        public init(error: FailbackReplicationError? = nil, rawError: String? = nil) {
            self.error = error
            self.rawError = rawError
        }

        private enum CodingKeys: String, CodingKey {
            case error
            case rawError
        }
    }

    public struct RecoveryInstanceDataReplicationInfo: AWSDecodableShape {
        /// Information about Data Replication
        public let dataReplicationError: RecoveryInstanceDataReplicationError?
        /// Information about whether the data replication has been initiated.
        public let dataReplicationInitiation: RecoveryInstanceDataReplicationInitiation?
        /// The state of the data replication.
        public let dataReplicationState: RecoveryInstanceDataReplicationState?
        /// An estimate of when the data replication will be completed.
        public let etaDateTime: String?
        /// Data replication lag duration.
        public let lagDuration: String?
        /// The disks that should be replicated.
        public let replicatedDisks: [RecoveryInstanceDataReplicationInfoReplicatedDisk]?

        public init(dataReplicationError: RecoveryInstanceDataReplicationError? = nil, dataReplicationInitiation: RecoveryInstanceDataReplicationInitiation? = nil, dataReplicationState: RecoveryInstanceDataReplicationState? = nil, etaDateTime: String? = nil, lagDuration: String? = nil, replicatedDisks: [RecoveryInstanceDataReplicationInfoReplicatedDisk]? = nil) {
            self.dataReplicationError = dataReplicationError
            self.dataReplicationInitiation = dataReplicationInitiation
            self.dataReplicationState = dataReplicationState
            self.etaDateTime = etaDateTime
            self.lagDuration = lagDuration
            self.replicatedDisks = replicatedDisks
        }

        private enum CodingKeys: String, CodingKey {
            case dataReplicationError
            case dataReplicationInitiation
            case dataReplicationState
            case etaDateTime
            case lagDuration
            case replicatedDisks
        }
    }

    public struct RecoveryInstanceDataReplicationInfoReplicatedDisk: AWSDecodableShape {
        /// The size of the replication backlog in bytes.
        public let backloggedStorageBytes: Int64?
        /// The name of the device.
        public let deviceName: String?
        /// The amount of data replicated so far in bytes.
        public let replicatedStorageBytes: Int64?
        /// The amount of data to be rescanned in bytes.
        public let rescannedStorageBytes: Int64?
        /// The total amount of data to be replicated in bytes.
        public let totalStorageBytes: Int64?

        public init(backloggedStorageBytes: Int64? = nil, deviceName: String? = nil, replicatedStorageBytes: Int64? = nil, rescannedStorageBytes: Int64? = nil, totalStorageBytes: Int64? = nil) {
            self.backloggedStorageBytes = backloggedStorageBytes
            self.deviceName = deviceName
            self.replicatedStorageBytes = replicatedStorageBytes
            self.rescannedStorageBytes = rescannedStorageBytes
            self.totalStorageBytes = totalStorageBytes
        }

        private enum CodingKeys: String, CodingKey {
            case backloggedStorageBytes
            case deviceName
            case replicatedStorageBytes
            case rescannedStorageBytes
            case totalStorageBytes
        }
    }

    public struct RecoveryInstanceDataReplicationInitiation: AWSDecodableShape {
        /// The date and time of the current attempt to initiate data replication.
        public let startDateTime: String?
        /// The steps of the current attempt to initiate data replication.
        public let steps: [RecoveryInstanceDataReplicationInitiationStep]?

        public init(startDateTime: String? = nil, steps: [RecoveryInstanceDataReplicationInitiationStep]? = nil) {
            self.startDateTime = startDateTime
            self.steps = steps
        }

        private enum CodingKeys: String, CodingKey {
            case startDateTime
            case steps
        }
    }

    public struct RecoveryInstanceDataReplicationInitiationStep: AWSDecodableShape {
        /// The name of the step.
        public let name: RecoveryInstanceDataReplicationInitiationStepName?
        /// The status of the step.
        public let status: RecoveryInstanceDataReplicationInitiationStepStatus?

        public init(name: RecoveryInstanceDataReplicationInitiationStepName? = nil, status: RecoveryInstanceDataReplicationInitiationStepStatus? = nil) {
            self.name = name
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case name
            case status
        }
    }

    public struct RecoveryInstanceDisk: AWSDecodableShape {
        /// The amount of storage on the disk in bytes.
        public let bytes: Int64?
        /// The EBS Volume ID of this disk.
        public let ebsVolumeID: String?
        /// The internal device name of this disk. This is the name that is visible on the machine itself and not from the EC2 console.
        public let internalDeviceName: String?

        public init(bytes: Int64? = nil, ebsVolumeID: String? = nil, internalDeviceName: String? = nil) {
            self.bytes = bytes
            self.ebsVolumeID = ebsVolumeID
            self.internalDeviceName = internalDeviceName
        }

        private enum CodingKeys: String, CodingKey {
            case bytes
            case ebsVolumeID
            case internalDeviceName
        }
    }

    public struct RecoveryInstanceFailback: AWSDecodableShape {
        /// The date and time the agent on the Recovery Instance was last seen by the service.
        public let agentLastSeenByServiceDateTime: String?
        /// The amount of time that the Recovery Instance has been replicating for.
        public let elapsedReplicationDuration: String?
        /// The ID of the failback client that this Recovery Instance is associated with.
        public let failbackClientID: String?
        /// The date and time that the failback client was last seen by the service.
        public let failbackClientLastSeenByServiceDateTime: String?
        /// The date and time that the failback initiation started.
        public let failbackInitiationTime: String?
        /// The Job ID of the last failback log for this Recovery Instance.
        public let failbackJobID: String?
        /// The launch type (Recovery / Drill) of the last launch for the failback replication of this recovery instance.
        public let failbackLaunchType: FailbackLaunchType?
        /// Whether we are failing back to the original Source Server for this Recovery Instance.
        public let failbackToOriginalServer: Bool?
        /// The date and time of the first byte that was replicated from the Recovery Instance.
        public let firstByteDateTime: String?
        /// The state of the failback process that this Recovery Instance is in.
        public let state: FailbackState?

        public init(agentLastSeenByServiceDateTime: String? = nil, elapsedReplicationDuration: String? = nil, failbackClientID: String? = nil, failbackClientLastSeenByServiceDateTime: String? = nil, failbackInitiationTime: String? = nil, failbackJobID: String? = nil, failbackLaunchType: FailbackLaunchType? = nil, failbackToOriginalServer: Bool? = nil, firstByteDateTime: String? = nil, state: FailbackState? = nil) {
            self.agentLastSeenByServiceDateTime = agentLastSeenByServiceDateTime
            self.elapsedReplicationDuration = elapsedReplicationDuration
            self.failbackClientID = failbackClientID
            self.failbackClientLastSeenByServiceDateTime = failbackClientLastSeenByServiceDateTime
            self.failbackInitiationTime = failbackInitiationTime
            self.failbackJobID = failbackJobID
            self.failbackLaunchType = failbackLaunchType
            self.failbackToOriginalServer = failbackToOriginalServer
            self.firstByteDateTime = firstByteDateTime
            self.state = state
        }

        private enum CodingKeys: String, CodingKey {
            case agentLastSeenByServiceDateTime
            case elapsedReplicationDuration
            case failbackClientID
            case failbackClientLastSeenByServiceDateTime
            case failbackInitiationTime
            case failbackJobID
            case failbackLaunchType
            case failbackToOriginalServer
            case firstByteDateTime
            case state
        }
    }

    public struct RecoveryInstanceProperties: AWSDecodableShape {
        /// An array of CPUs.
        public let cpus: [CPU]?
        /// An array of disks.
        public let disks: [RecoveryInstanceDisk]?
        /// Hints used to uniquely identify a machine.
        public let identificationHints: IdentificationHints?
        /// The date and time the Recovery Instance properties were last updated on.
        public let lastUpdatedDateTime: String?
        /// An array of network interfaces.
        public let networkInterfaces: [NetworkInterface]?
        /// Operating system.
        public let os: OS?
        /// The amount of RAM in bytes.
        public let ramBytes: Int64?

        public init(cpus: [CPU]? = nil, disks: [RecoveryInstanceDisk]? = nil, identificationHints: IdentificationHints? = nil, lastUpdatedDateTime: String? = nil, networkInterfaces: [NetworkInterface]? = nil, os: OS? = nil, ramBytes: Int64? = nil) {
            self.cpus = cpus
            self.disks = disks
            self.identificationHints = identificationHints
            self.lastUpdatedDateTime = lastUpdatedDateTime
            self.networkInterfaces = networkInterfaces
            self.os = os
            self.ramBytes = ramBytes
        }

        private enum CodingKeys: String, CodingKey {
            case cpus
            case disks
            case identificationHints
            case lastUpdatedDateTime
            case networkInterfaces
            case os
            case ramBytes
        }
    }

    public struct RecoverySnapshot: AWSDecodableShape {
        /// A list of EBS snapshots.
        public let ebsSnapshots: [String]?
        /// The timestamp of when we expect the snapshot to be taken.
        public let expectedTimestamp: String
        /// The ID of the Recovery Snapshot.
        public let snapshotID: String
        /// The ID of the Source Server that the snapshot was taken for.
        public let sourceServerID: String
        /// The actual timestamp that the snapshot was taken.
        public let timestamp: String?

        public init(ebsSnapshots: [String]? = nil, expectedTimestamp: String, snapshotID: String, sourceServerID: String, timestamp: String? = nil) {
            self.ebsSnapshots = ebsSnapshots
            self.expectedTimestamp = expectedTimestamp
            self.snapshotID = snapshotID
            self.sourceServerID = sourceServerID
            self.timestamp = timestamp
        }

        private enum CodingKeys: String, CodingKey {
            case ebsSnapshots
            case expectedTimestamp
            case snapshotID
            case sourceServerID
            case timestamp
        }
    }

    public struct ReplicationConfiguration: AWSDecodableShape {
        /// Whether to associate the default Elastic Disaster Recovery Security group with the Replication Configuration.
        public let associateDefaultSecurityGroup: Bool?
        /// Configure bandwidth throttling for the outbound data transfer rate of the Source Server in Mbps.
        public let bandwidthThrottling: Int64?
        /// Whether to create a Public IP for the Recovery Instance by default.
        public let createPublicIP: Bool?
        /// The data plane routing mechanism that will be used for replication.
        public let dataPlaneRouting: ReplicationConfigurationDataPlaneRouting?
        /// The Staging Disk EBS volume type to be used during replication.
        public let defaultLargeStagingDiskType: ReplicationConfigurationDefaultLargeStagingDiskType?
        /// The type of EBS encryption to be used during replication.
        public let ebsEncryption: ReplicationConfigurationEbsEncryption?
        /// The ARN of the EBS encryption key to be used during replication.
        public let ebsEncryptionKeyArn: String?
        /// The name of the Replication Configuration.
        public let name: String?
        /// The Point in time (PIT) policy to manage snapshots taken during replication.
        public let pitPolicy: [PITPolicyRule]?
        /// The configuration of the disks of the Source Server to be replicated.
        public let replicatedDisks: [ReplicationConfigurationReplicatedDisk]?
        /// The instance type to be used for the replication server.
        public let replicationServerInstanceType: String?
        /// The security group IDs that will be used by the replication server.
        public let replicationServersSecurityGroupsIDs: [String]?
        /// The ID of the Source Server for this Replication Configuration.
        public let sourceServerID: String?
        /// The subnet to be used by the replication staging area.
        public let stagingAreaSubnetId: String?
        /// A set of tags to be associated with all resources created in the replication staging area: EC2 replication server, EBS volumes, EBS snapshots, etc.
        public let stagingAreaTags: [String: String]?
        /// Whether to use a dedicated Replication Server in the replication staging area.
        public let useDedicatedReplicationServer: Bool?

        public init(associateDefaultSecurityGroup: Bool? = nil, bandwidthThrottling: Int64? = nil, createPublicIP: Bool? = nil, dataPlaneRouting: ReplicationConfigurationDataPlaneRouting? = nil, defaultLargeStagingDiskType: ReplicationConfigurationDefaultLargeStagingDiskType? = nil, ebsEncryption: ReplicationConfigurationEbsEncryption? = nil, ebsEncryptionKeyArn: String? = nil, name: String? = nil, pitPolicy: [PITPolicyRule]? = nil, replicatedDisks: [ReplicationConfigurationReplicatedDisk]? = nil, replicationServerInstanceType: String? = nil, replicationServersSecurityGroupsIDs: [String]? = nil, sourceServerID: String? = nil, stagingAreaSubnetId: String? = nil, stagingAreaTags: [String: String]? = nil, useDedicatedReplicationServer: Bool? = nil) {
            self.associateDefaultSecurityGroup = associateDefaultSecurityGroup
            self.bandwidthThrottling = bandwidthThrottling
            self.createPublicIP = createPublicIP
            self.dataPlaneRouting = dataPlaneRouting
            self.defaultLargeStagingDiskType = defaultLargeStagingDiskType
            self.ebsEncryption = ebsEncryption
            self.ebsEncryptionKeyArn = ebsEncryptionKeyArn
            self.name = name
            self.pitPolicy = pitPolicy
            self.replicatedDisks = replicatedDisks
            self.replicationServerInstanceType = replicationServerInstanceType
            self.replicationServersSecurityGroupsIDs = replicationServersSecurityGroupsIDs
            self.sourceServerID = sourceServerID
            self.stagingAreaSubnetId = stagingAreaSubnetId
            self.stagingAreaTags = stagingAreaTags
            self.useDedicatedReplicationServer = useDedicatedReplicationServer
        }

        private enum CodingKeys: String, CodingKey {
            case associateDefaultSecurityGroup
            case bandwidthThrottling
            case createPublicIP
            case dataPlaneRouting
            case defaultLargeStagingDiskType
            case ebsEncryption
            case ebsEncryptionKeyArn
            case name
            case pitPolicy
            case replicatedDisks
            case replicationServerInstanceType
            case replicationServersSecurityGroupsIDs
            case sourceServerID
            case stagingAreaSubnetId
            case stagingAreaTags
            case useDedicatedReplicationServer
        }
    }

    public struct ReplicationConfigurationReplicatedDisk: AWSEncodableShape & AWSDecodableShape {
        /// The name of the device.
        public let deviceName: String?
        /// The requested number of I/O operations per second (IOPS).
        public let iops: Int64?
        /// Whether to boot from this disk or not.
        public let isBootDisk: Bool?
        /// When stagingDiskType is set to Auto, this field shows the current staging disk EBS volume type as it is constantly updated by the service. This is a read-only field.
        public let optimizedStagingDiskType: ReplicationConfigurationReplicatedDiskStagingDiskType?
        /// The Staging Disk EBS volume type to be used during replication.
        public let stagingDiskType: ReplicationConfigurationReplicatedDiskStagingDiskType?
        /// The throughput to use for the EBS volume in MiB/s. This parameter is valid only for gp3 volumes.
        public let throughput: Int64?

        public init(deviceName: String? = nil, iops: Int64? = nil, isBootDisk: Bool? = nil, optimizedStagingDiskType: ReplicationConfigurationReplicatedDiskStagingDiskType? = nil, stagingDiskType: ReplicationConfigurationReplicatedDiskStagingDiskType? = nil, throughput: Int64? = nil) {
            self.deviceName = deviceName
            self.iops = iops
            self.isBootDisk = isBootDisk
            self.optimizedStagingDiskType = optimizedStagingDiskType
            self.stagingDiskType = stagingDiskType
            self.throughput = throughput
        }

        public func validate(name: String) throws {
            try self.validate(self.deviceName, name: "deviceName", parent: name, max: 256)
            try self.validate(self.iops, name: "iops", parent: name, min: 0)
            try self.validate(self.throughput, name: "throughput", parent: name, min: 0)
        }

        private enum CodingKeys: String, CodingKey {
            case deviceName
            case iops
            case isBootDisk
            case optimizedStagingDiskType
            case stagingDiskType
            case throughput
        }
    }

    public struct ReplicationConfigurationTemplate: AWSDecodableShape {
        /// The Replication Configuration Template ARN.
        public let arn: String?
        /// Whether to associate the default Elastic Disaster Recovery Security group with the Replication Configuration Template.
        public let associateDefaultSecurityGroup: Bool?
        /// Configure bandwidth throttling for the outbound data transfer rate of the Source Server in Mbps.
        public let bandwidthThrottling: Int64?
        /// Whether to create a Public IP for the Recovery Instance by default.
        public let createPublicIP: Bool?
        /// The data plane routing mechanism that will be used for replication.
        public let dataPlaneRouting: ReplicationConfigurationDataPlaneRouting?
        /// The Staging Disk EBS volume type to be used during replication.
        public let defaultLargeStagingDiskType: ReplicationConfigurationDefaultLargeStagingDiskType?
        /// The type of EBS encryption to be used during replication.
        public let ebsEncryption: ReplicationConfigurationEbsEncryption?
        /// The ARN of the EBS encryption key to be used during replication.
        public let ebsEncryptionKeyArn: String?
        /// The Point in time (PIT) policy to manage snapshots taken during replication.
        public let pitPolicy: [PITPolicyRule]?
        /// The Replication Configuration Template ID.
        public let replicationConfigurationTemplateID: String
        /// The instance type to be used for the replication server.
        public let replicationServerInstanceType: String?
        /// The security group IDs that will be used by the replication server.
        public let replicationServersSecurityGroupsIDs: [String]?
        /// The subnet to be used by the replication staging area.
        public let stagingAreaSubnetId: String?
        /// A set of tags to be associated with all resources created in the replication staging area: EC2 replication server, EBS volumes, EBS snapshots, etc.
        public let stagingAreaTags: [String: String]?
        /// A set of tags to be associated with the Replication Configuration Template resource.
        public let tags: [String: String]?
        /// Whether to use a dedicated Replication Server in the replication staging area.
        public let useDedicatedReplicationServer: Bool?

        public init(arn: String? = nil, associateDefaultSecurityGroup: Bool? = nil, bandwidthThrottling: Int64? = nil, createPublicIP: Bool? = nil, dataPlaneRouting: ReplicationConfigurationDataPlaneRouting? = nil, defaultLargeStagingDiskType: ReplicationConfigurationDefaultLargeStagingDiskType? = nil, ebsEncryption: ReplicationConfigurationEbsEncryption? = nil, ebsEncryptionKeyArn: String? = nil, pitPolicy: [PITPolicyRule]? = nil, replicationConfigurationTemplateID: String, replicationServerInstanceType: String? = nil, replicationServersSecurityGroupsIDs: [String]? = nil, stagingAreaSubnetId: String? = nil, stagingAreaTags: [String: String]? = nil, tags: [String: String]? = nil, useDedicatedReplicationServer: Bool? = nil) {
            self.arn = arn
            self.associateDefaultSecurityGroup = associateDefaultSecurityGroup
            self.bandwidthThrottling = bandwidthThrottling
            self.createPublicIP = createPublicIP
            self.dataPlaneRouting = dataPlaneRouting
            self.defaultLargeStagingDiskType = defaultLargeStagingDiskType
            self.ebsEncryption = ebsEncryption
            self.ebsEncryptionKeyArn = ebsEncryptionKeyArn
            self.pitPolicy = pitPolicy
            self.replicationConfigurationTemplateID = replicationConfigurationTemplateID
            self.replicationServerInstanceType = replicationServerInstanceType
            self.replicationServersSecurityGroupsIDs = replicationServersSecurityGroupsIDs
            self.stagingAreaSubnetId = stagingAreaSubnetId
            self.stagingAreaTags = stagingAreaTags
            self.tags = tags
            self.useDedicatedReplicationServer = useDedicatedReplicationServer
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case associateDefaultSecurityGroup
            case bandwidthThrottling
            case createPublicIP
            case dataPlaneRouting
            case defaultLargeStagingDiskType
            case ebsEncryption
            case ebsEncryptionKeyArn
            case pitPolicy
            case replicationConfigurationTemplateID
            case replicationServerInstanceType
            case replicationServersSecurityGroupsIDs
            case stagingAreaSubnetId
            case stagingAreaTags
            case tags
            case useDedicatedReplicationServer
        }
    }

    public struct RetryDataReplicationRequest: AWSEncodableShape {
        /// The ID of the Source Server whose data replication should be retried.
        public let sourceServerID: String

        public init(sourceServerID: String) {
            self.sourceServerID = sourceServerID
        }

        public func validate(name: String) throws {
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, max: 19)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, min: 19)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, pattern: "^s-[0-9a-zA-Z]{17}$")
        }

        private enum CodingKeys: String, CodingKey {
            case sourceServerID
        }
    }

    public struct ReverseReplicationRequest: AWSEncodableShape {
        /// The ID of the Recovery Instance that we want to reverse the replication for.
        public let recoveryInstanceID: String

        public init(recoveryInstanceID: String) {
            self.recoveryInstanceID = recoveryInstanceID
        }

        public func validate(name: String) throws {
            try self.validate(self.recoveryInstanceID, name: "recoveryInstanceID", parent: name, max: 19)
            try self.validate(self.recoveryInstanceID, name: "recoveryInstanceID", parent: name, min: 10)
            try self.validate(self.recoveryInstanceID, name: "recoveryInstanceID", parent: name, pattern: "^i-[0-9a-fA-F]{8,}$")
        }

        private enum CodingKeys: String, CodingKey {
            case recoveryInstanceID
        }
    }

    public struct ReverseReplicationResponse: AWSDecodableShape {
        /// ARN of created SourceServer.
        public let reversedDirectionSourceServerArn: String?

        public init(reversedDirectionSourceServerArn: String? = nil) {
            self.reversedDirectionSourceServerArn = reversedDirectionSourceServerArn
        }

        private enum CodingKeys: String, CodingKey {
            case reversedDirectionSourceServerArn
        }
    }

    public struct SourceCloudProperties: AWSDecodableShape {
        /// AWS Account ID for an EC2-originated Source Server.
        public let originAccountID: String?
        /// AWS Availability Zone for an EC2-originated Source Server.
        public let originAvailabilityZone: String?
        /// AWS Region for an EC2-originated Source Server.
        public let originRegion: String?

        public init(originAccountID: String? = nil, originAvailabilityZone: String? = nil, originRegion: String? = nil) {
            self.originAccountID = originAccountID
            self.originAvailabilityZone = originAvailabilityZone
            self.originRegion = originRegion
        }

        private enum CodingKeys: String, CodingKey {
            case originAccountID
            case originAvailabilityZone
            case originRegion
        }
    }

    public struct SourceProperties: AWSDecodableShape {
        /// An array of CPUs.
        public let cpus: [CPU]?
        /// An array of disks.
        public let disks: [Disk]?
        /// Hints used to uniquely identify a machine.
        public let identificationHints: IdentificationHints?
        /// The date and time the Source Properties were last updated on.
        public let lastUpdatedDateTime: String?
        /// An array of network interfaces.
        public let networkInterfaces: [NetworkInterface]?
        /// Operating system.
        public let os: OS?
        /// The amount of RAM in bytes.
        public let ramBytes: Int64?
        /// The recommended EC2 instance type that will be used when recovering the Source Server.
        public let recommendedInstanceType: String?

        public init(cpus: [CPU]? = nil, disks: [Disk]? = nil, identificationHints: IdentificationHints? = nil, lastUpdatedDateTime: String? = nil, networkInterfaces: [NetworkInterface]? = nil, os: OS? = nil, ramBytes: Int64? = nil, recommendedInstanceType: String? = nil) {
            self.cpus = cpus
            self.disks = disks
            self.identificationHints = identificationHints
            self.lastUpdatedDateTime = lastUpdatedDateTime
            self.networkInterfaces = networkInterfaces
            self.os = os
            self.ramBytes = ramBytes
            self.recommendedInstanceType = recommendedInstanceType
        }

        private enum CodingKeys: String, CodingKey {
            case cpus
            case disks
            case identificationHints
            case lastUpdatedDateTime
            case networkInterfaces
            case os
            case ramBytes
            case recommendedInstanceType
        }
    }

    public struct SourceServer: AWSDecodableShape {
        /// The ARN of the Source Server.
        public let arn: String?
        /// The Data Replication Info of the Source Server.
        public let dataReplicationInfo: DataReplicationInfo?
        /// The status of the last recovery launch of this Source Server.
        public let lastLaunchResult: LastLaunchResult?
        /// The lifecycle information of this Source Server.
        public let lifeCycle: LifeCycle?
        /// The ID of the Recovery Instance associated with this Source Server.
        public let recoveryInstanceId: String?
        /// Replication direction of the Source Server.
        public let replicationDirection: ReplicationDirection?
        /// For EC2-originated Source Servers which have been failed over and then failed back, this value will mean the ARN of the Source Server on the opposite replication direction.
        public let reversedDirectionSourceServerArn: String?
        /// Source cloud properties of the Source Server.
        public let sourceCloudProperties: SourceCloudProperties?
        /// The source properties of the Source Server.
        public let sourceProperties: SourceProperties?
        /// The ID of the Source Server.
        public let sourceServerID: String?
        /// The staging area of the source server.
        public let stagingArea: StagingArea?
        /// The tags associated with the Source Server.
        public let tags: [String: String]?

        public init(arn: String? = nil, dataReplicationInfo: DataReplicationInfo? = nil, lastLaunchResult: LastLaunchResult? = nil, lifeCycle: LifeCycle? = nil, recoveryInstanceId: String? = nil, replicationDirection: ReplicationDirection? = nil, reversedDirectionSourceServerArn: String? = nil, sourceCloudProperties: SourceCloudProperties? = nil, sourceProperties: SourceProperties? = nil, sourceServerID: String? = nil, stagingArea: StagingArea? = nil, tags: [String: String]? = nil) {
            self.arn = arn
            self.dataReplicationInfo = dataReplicationInfo
            self.lastLaunchResult = lastLaunchResult
            self.lifeCycle = lifeCycle
            self.recoveryInstanceId = recoveryInstanceId
            self.replicationDirection = replicationDirection
            self.reversedDirectionSourceServerArn = reversedDirectionSourceServerArn
            self.sourceCloudProperties = sourceCloudProperties
            self.sourceProperties = sourceProperties
            self.sourceServerID = sourceServerID
            self.stagingArea = stagingArea
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case dataReplicationInfo
            case lastLaunchResult
            case lifeCycle
            case recoveryInstanceId
            case replicationDirection
            case reversedDirectionSourceServerArn
            case sourceCloudProperties
            case sourceProperties
            case sourceServerID
            case stagingArea
            case tags
        }
    }

    public struct StagingArea: AWSDecodableShape {
        /// Shows an error message that occurred when DRS tried to access the staging source server. In this case StagingArea$status will have value EXTENSION_ERROR
        public let errorMessage: String?
        /// Account ID of the account to which source server belongs. If this source server is extended - shows Account ID of staging source server.
        public let stagingAccountID: String?
        /// Arn of the staging source server if this source server is extended
        public let stagingSourceServerArn: String?
        /// Status of Source server extension. Possible values: (a) NOT_EXTENDED - This is a source server that is replicating in the current account. (b) EXTENDED - Source server is extended from a staging source server. In this case, the value of stagingSourceServerArn is pointing to the Arn of the source server in the staging account. (c) EXTENSION_ERROR - Some issue occurred when accessing staging source server. In this case, errorMessage field will contain an error message that explains what happened.
        public let status: ExtensionStatus?

        public init(errorMessage: String? = nil, stagingAccountID: String? = nil, stagingSourceServerArn: String? = nil, status: ExtensionStatus? = nil) {
            self.errorMessage = errorMessage
            self.stagingAccountID = stagingAccountID
            self.stagingSourceServerArn = stagingSourceServerArn
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case errorMessage
            case stagingAccountID
            case stagingSourceServerArn
            case status
        }
    }

    public struct StagingSourceServer: AWSDecodableShape {
        /// The ARN of the source server.
        public let arn: String?
        /// Hostname of staging source server.
        public let hostname: String?
        /// A list of tags associated with the staging source server.
        public let tags: [String: String]?

        public init(arn: String? = nil, hostname: String? = nil, tags: [String: String]? = nil) {
            self.arn = arn
            self.hostname = hostname
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case hostname
            case tags
        }
    }

    public struct StartFailbackLaunchRequest: AWSEncodableShape {
        /// The IDs of the Recovery Instance whose failback launch we want to request.
        public let recoveryInstanceIDs: [String]
        /// The tags to be associated with the failback launch Job.
        public let tags: [String: String]?

        public init(recoveryInstanceIDs: [String], tags: [String: String]? = nil) {
            self.recoveryInstanceIDs = recoveryInstanceIDs
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.recoveryInstanceIDs.forEach {
                try validate($0, name: "recoveryInstanceIDs[]", parent: name, max: 19)
                try validate($0, name: "recoveryInstanceIDs[]", parent: name, min: 10)
                try validate($0, name: "recoveryInstanceIDs[]", parent: name, pattern: "^i-[0-9a-fA-F]{8,}$")
            }
            try self.validate(self.recoveryInstanceIDs, name: "recoveryInstanceIDs", parent: name, max: 200)
            try self.validate(self.recoveryInstanceIDs, name: "recoveryInstanceIDs", parent: name, min: 1)
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case recoveryInstanceIDs
            case tags
        }
    }

    public struct StartFailbackLaunchResponse: AWSDecodableShape {
        /// The failback launch Job.
        public let job: Job?

        public init(job: Job? = nil) {
            self.job = job
        }

        private enum CodingKeys: String, CodingKey {
            case job
        }
    }

    public struct StartRecoveryRequest: AWSEncodableShape {
        /// Whether this Source Server Recovery operation is a drill or not.
        public let isDrill: Bool?
        /// The Source Servers that we want to start a Recovery Job for.
        public let sourceServers: [StartRecoveryRequestSourceServer]
        /// The tags to be associated with the Recovery Job.
        public let tags: [String: String]?

        public init(isDrill: Bool? = nil, sourceServers: [StartRecoveryRequestSourceServer], tags: [String: String]? = nil) {
            self.isDrill = isDrill
            self.sourceServers = sourceServers
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.sourceServers.forEach {
                try $0.validate(name: "\(name).sourceServers[]")
            }
            try self.validate(self.sourceServers, name: "sourceServers", parent: name, max: 200)
            try self.validate(self.sourceServers, name: "sourceServers", parent: name, min: 1)
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case isDrill
            case sourceServers
            case tags
        }
    }

    public struct StartRecoveryRequestSourceServer: AWSEncodableShape {
        /// The ID of a Recovery Snapshot we want to recover from. Omit this field to launch from the latest data by taking an on-demand snapshot.
        public let recoverySnapshotID: String?
        /// The ID of the Source Server you want to recover.
        public let sourceServerID: String

        public init(recoverySnapshotID: String? = nil, sourceServerID: String) {
            self.recoverySnapshotID = recoverySnapshotID
            self.sourceServerID = sourceServerID
        }

        public func validate(name: String) throws {
            try self.validate(self.recoverySnapshotID, name: "recoverySnapshotID", parent: name, max: 21)
            try self.validate(self.recoverySnapshotID, name: "recoverySnapshotID", parent: name, min: 21)
            try self.validate(self.recoverySnapshotID, name: "recoverySnapshotID", parent: name, pattern: "^pit-[0-9a-zA-Z]{17}$")
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, max: 19)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, min: 19)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, pattern: "^s-[0-9a-zA-Z]{17}$")
        }

        private enum CodingKeys: String, CodingKey {
            case recoverySnapshotID
            case sourceServerID
        }
    }

    public struct StartRecoveryResponse: AWSDecodableShape {
        /// The Recovery Job.
        public let job: Job?

        public init(job: Job? = nil) {
            self.job = job
        }

        private enum CodingKeys: String, CodingKey {
            case job
        }
    }

    public struct StartReplicationRequest: AWSEncodableShape {
        /// The ID of the Source Server to start replication for.
        public let sourceServerID: String

        public init(sourceServerID: String) {
            self.sourceServerID = sourceServerID
        }

        public func validate(name: String) throws {
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, max: 19)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, min: 19)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, pattern: "^s-[0-9a-zA-Z]{17}$")
        }

        private enum CodingKeys: String, CodingKey {
            case sourceServerID
        }
    }

    public struct StartReplicationResponse: AWSDecodableShape {
        /// The Source Server that this action was targeted on.
        public let sourceServer: SourceServer?

        public init(sourceServer: SourceServer? = nil) {
            self.sourceServer = sourceServer
        }

        private enum CodingKeys: String, CodingKey {
            case sourceServer
        }
    }

    public struct StopFailbackRequest: AWSEncodableShape {
        /// The ID of the Recovery Instance we want to stop failback for.
        public let recoveryInstanceID: String

        public init(recoveryInstanceID: String) {
            self.recoveryInstanceID = recoveryInstanceID
        }

        public func validate(name: String) throws {
            try self.validate(self.recoveryInstanceID, name: "recoveryInstanceID", parent: name, max: 19)
            try self.validate(self.recoveryInstanceID, name: "recoveryInstanceID", parent: name, min: 10)
            try self.validate(self.recoveryInstanceID, name: "recoveryInstanceID", parent: name, pattern: "^i-[0-9a-fA-F]{8,}$")
        }

        private enum CodingKeys: String, CodingKey {
            case recoveryInstanceID
        }
    }

    public struct StopReplicationRequest: AWSEncodableShape {
        /// The ID of the Source Server to stop replication for.
        public let sourceServerID: String

        public init(sourceServerID: String) {
            self.sourceServerID = sourceServerID
        }

        public func validate(name: String) throws {
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, max: 19)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, min: 19)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, pattern: "^s-[0-9a-zA-Z]{17}$")
        }

        private enum CodingKeys: String, CodingKey {
            case sourceServerID
        }
    }

    public struct StopReplicationResponse: AWSDecodableShape {
        /// The Source Server that this action was targeted on.
        public let sourceServer: SourceServer?

        public init(sourceServer: SourceServer? = nil) {
            self.sourceServer = sourceServer
        }

        private enum CodingKeys: String, CodingKey {
            case sourceServer
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("resourceArn"))
        ]

        /// ARN of the resource for which tags are to be added or updated.
        public let resourceArn: String
        /// Array of tags to be added or updated.
        public let tags: [String: String]

        public init(resourceArn: String, tags: [String: String]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 2048)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 20)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:.{16,2044}$")
            try self.tags.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case tags
        }
    }

    public struct TerminateRecoveryInstancesRequest: AWSEncodableShape {
        /// The IDs of the Recovery Instances that should be terminated.
        public let recoveryInstanceIDs: [String]

        public init(recoveryInstanceIDs: [String]) {
            self.recoveryInstanceIDs = recoveryInstanceIDs
        }

        public func validate(name: String) throws {
            try self.recoveryInstanceIDs.forEach {
                try validate($0, name: "recoveryInstanceIDs[]", parent: name, max: 19)
                try validate($0, name: "recoveryInstanceIDs[]", parent: name, min: 10)
                try validate($0, name: "recoveryInstanceIDs[]", parent: name, pattern: "^i-[0-9a-fA-F]{8,}$")
            }
            try self.validate(self.recoveryInstanceIDs, name: "recoveryInstanceIDs", parent: name, max: 200)
            try self.validate(self.recoveryInstanceIDs, name: "recoveryInstanceIDs", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case recoveryInstanceIDs
        }
    }

    public struct TerminateRecoveryInstancesResponse: AWSDecodableShape {
        /// The Job for terminating the Recovery Instances.
        public let job: Job?

        public init(job: Job? = nil) {
            self.job = job
        }

        private enum CodingKeys: String, CodingKey {
            case job
        }
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("resourceArn")),
            AWSMemberEncoding(label: "tagKeys", location: .querystring("tagKeys"))
        ]

        /// ARN of the resource for which tags are to be removed.
        public let resourceArn: String
        /// Array of tags to be removed.
        public let tagKeys: [String]

        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 2048)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 20)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:.{16,2044}$")
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 256)
            }
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct UpdateFailbackReplicationConfigurationRequest: AWSEncodableShape {
        /// Configure bandwidth throttling for the outbound data transfer rate of the Recovery Instance in Mbps.
        public let bandwidthThrottling: Int64?
        /// The name of the Failback Replication Configuration.
        public let name: String?
        /// The ID of the Recovery Instance.
        public let recoveryInstanceID: String
        /// Whether to use Private IP for the failback replication of the Recovery Instance.
        public let usePrivateIP: Bool?

        public init(bandwidthThrottling: Int64? = nil, name: String? = nil, recoveryInstanceID: String, usePrivateIP: Bool? = nil) {
            self.bandwidthThrottling = bandwidthThrottling
            self.name = name
            self.recoveryInstanceID = recoveryInstanceID
            self.usePrivateIP = usePrivateIP
        }

        public func validate(name: String) throws {
            try self.validate(self.bandwidthThrottling, name: "bandwidthThrottling", parent: name, min: 0)
            try self.validate(self.name, name: "name", parent: name, max: 256)
            try self.validate(self.recoveryInstanceID, name: "recoveryInstanceID", parent: name, max: 19)
            try self.validate(self.recoveryInstanceID, name: "recoveryInstanceID", parent: name, min: 10)
            try self.validate(self.recoveryInstanceID, name: "recoveryInstanceID", parent: name, pattern: "^i-[0-9a-fA-F]{8,}$")
        }

        private enum CodingKeys: String, CodingKey {
            case bandwidthThrottling
            case name
            case recoveryInstanceID
            case usePrivateIP
        }
    }

    public struct UpdateLaunchConfigurationRequest: AWSEncodableShape {
        /// Whether we should copy the Private IP of the Source Server to the Recovery Instance.
        public let copyPrivateIp: Bool?
        /// Whether we want to copy the tags of the Source Server to the EC2 machine of the Recovery Instance.
        public let copyTags: Bool?
        /// The state of the Recovery Instance in EC2 after the recovery operation.
        public let launchDisposition: LaunchDisposition?
        /// The licensing configuration to be used for this launch configuration.
        public let licensing: Licensing?
        /// The name of the launch configuration.
        public let name: String?
        /// The ID of the Source Server that we want to retrieve a Launch Configuration for.
        public let sourceServerID: String
        /// Whether Elastic Disaster Recovery should try to automatically choose the instance type that best matches the OS, CPU, and RAM of your Source Server.
        public let targetInstanceTypeRightSizingMethod: TargetInstanceTypeRightSizingMethod?

        public init(copyPrivateIp: Bool? = nil, copyTags: Bool? = nil, launchDisposition: LaunchDisposition? = nil, licensing: Licensing? = nil, name: String? = nil, sourceServerID: String, targetInstanceTypeRightSizingMethod: TargetInstanceTypeRightSizingMethod? = nil) {
            self.copyPrivateIp = copyPrivateIp
            self.copyTags = copyTags
            self.launchDisposition = launchDisposition
            self.licensing = licensing
            self.name = name
            self.sourceServerID = sourceServerID
            self.targetInstanceTypeRightSizingMethod = targetInstanceTypeRightSizingMethod
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 128)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, max: 19)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, min: 19)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, pattern: "^s-[0-9a-zA-Z]{17}$")
        }

        private enum CodingKeys: String, CodingKey {
            case copyPrivateIp
            case copyTags
            case launchDisposition
            case licensing
            case name
            case sourceServerID
            case targetInstanceTypeRightSizingMethod
        }
    }

    public struct UpdateReplicationConfigurationRequest: AWSEncodableShape {
        /// Whether to associate the default Elastic Disaster Recovery Security group with the Replication Configuration.
        public let associateDefaultSecurityGroup: Bool?
        /// Configure bandwidth throttling for the outbound data transfer rate of the Source Server in Mbps.
        public let bandwidthThrottling: Int64?
        /// Whether to create a Public IP for the Recovery Instance by default.
        public let createPublicIP: Bool?
        /// The data plane routing mechanism that will be used for replication.
        public let dataPlaneRouting: ReplicationConfigurationDataPlaneRouting?
        /// The Staging Disk EBS volume type to be used during replication.
        public let defaultLargeStagingDiskType: ReplicationConfigurationDefaultLargeStagingDiskType?
        /// The type of EBS encryption to be used during replication.
        public let ebsEncryption: ReplicationConfigurationEbsEncryption?
        /// The ARN of the EBS encryption key to be used during replication.
        public let ebsEncryptionKeyArn: String?
        /// The name of the Replication Configuration.
        public let name: String?
        /// The Point in time (PIT) policy to manage snapshots taken during replication.
        public let pitPolicy: [PITPolicyRule]?
        /// The configuration of the disks of the Source Server to be replicated.
        public let replicatedDisks: [ReplicationConfigurationReplicatedDisk]?
        /// The instance type to be used for the replication server.
        public let replicationServerInstanceType: String?
        /// The security group IDs that will be used by the replication server.
        public let replicationServersSecurityGroupsIDs: [String]?
        /// The ID of the Source Server for this Replication Configuration.
        public let sourceServerID: String
        /// The subnet to be used by the replication staging area.
        public let stagingAreaSubnetId: String?
        /// A set of tags to be associated with all resources created in the replication staging area: EC2 replication server, EBS volumes, EBS snapshots, etc.
        public let stagingAreaTags: [String: String]?
        /// Whether to use a dedicated Replication Server in the replication staging area.
        public let useDedicatedReplicationServer: Bool?

        public init(associateDefaultSecurityGroup: Bool? = nil, bandwidthThrottling: Int64? = nil, createPublicIP: Bool? = nil, dataPlaneRouting: ReplicationConfigurationDataPlaneRouting? = nil, defaultLargeStagingDiskType: ReplicationConfigurationDefaultLargeStagingDiskType? = nil, ebsEncryption: ReplicationConfigurationEbsEncryption? = nil, ebsEncryptionKeyArn: String? = nil, name: String? = nil, pitPolicy: [PITPolicyRule]? = nil, replicatedDisks: [ReplicationConfigurationReplicatedDisk]? = nil, replicationServerInstanceType: String? = nil, replicationServersSecurityGroupsIDs: [String]? = nil, sourceServerID: String, stagingAreaSubnetId: String? = nil, stagingAreaTags: [String: String]? = nil, useDedicatedReplicationServer: Bool? = nil) {
            self.associateDefaultSecurityGroup = associateDefaultSecurityGroup
            self.bandwidthThrottling = bandwidthThrottling
            self.createPublicIP = createPublicIP
            self.dataPlaneRouting = dataPlaneRouting
            self.defaultLargeStagingDiskType = defaultLargeStagingDiskType
            self.ebsEncryption = ebsEncryption
            self.ebsEncryptionKeyArn = ebsEncryptionKeyArn
            self.name = name
            self.pitPolicy = pitPolicy
            self.replicatedDisks = replicatedDisks
            self.replicationServerInstanceType = replicationServerInstanceType
            self.replicationServersSecurityGroupsIDs = replicationServersSecurityGroupsIDs
            self.sourceServerID = sourceServerID
            self.stagingAreaSubnetId = stagingAreaSubnetId
            self.stagingAreaTags = stagingAreaTags
            self.useDedicatedReplicationServer = useDedicatedReplicationServer
        }

        public func validate(name: String) throws {
            try self.validate(self.bandwidthThrottling, name: "bandwidthThrottling", parent: name, min: 0)
            try self.validate(self.ebsEncryptionKeyArn, name: "ebsEncryptionKeyArn", parent: name, max: 2048)
            try self.validate(self.ebsEncryptionKeyArn, name: "ebsEncryptionKeyArn", parent: name, min: 20)
            try self.validate(self.ebsEncryptionKeyArn, name: "ebsEncryptionKeyArn", parent: name, pattern: "^arn:.{16,2044}$")
            try self.validate(self.name, name: "name", parent: name, max: 128)
            try self.pitPolicy?.forEach {
                try $0.validate(name: "\(name).pitPolicy[]")
            }
            try self.validate(self.pitPolicy, name: "pitPolicy", parent: name, max: 10)
            try self.validate(self.pitPolicy, name: "pitPolicy", parent: name, min: 1)
            try self.replicatedDisks?.forEach {
                try $0.validate(name: "\(name).replicatedDisks[]")
            }
            try self.validate(self.replicatedDisks, name: "replicatedDisks", parent: name, max: 60)
            try self.validate(self.replicationServerInstanceType, name: "replicationServerInstanceType", parent: name, max: 255)
            try self.replicationServersSecurityGroupsIDs?.forEach {
                try validate($0, name: "replicationServersSecurityGroupsIDs[]", parent: name, max: 255)
                try validate($0, name: "replicationServersSecurityGroupsIDs[]", parent: name, pattern: "^sg-[0-9a-fA-F]{8,}$")
            }
            try self.validate(self.replicationServersSecurityGroupsIDs, name: "replicationServersSecurityGroupsIDs", parent: name, max: 32)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, max: 19)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, min: 19)
            try self.validate(self.sourceServerID, name: "sourceServerID", parent: name, pattern: "^s-[0-9a-zA-Z]{17}$")
            try self.validate(self.stagingAreaSubnetId, name: "stagingAreaSubnetId", parent: name, max: 255)
            try self.validate(self.stagingAreaSubnetId, name: "stagingAreaSubnetId", parent: name, pattern: "^subnet-[0-9a-fA-F]{8,}$")
            try self.stagingAreaTags?.forEach {
                try validate($0.key, name: "stagingAreaTags.key", parent: name, max: 256)
                try validate($0.value, name: "stagingAreaTags[\"\($0.key)\"]", parent: name, max: 256)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case associateDefaultSecurityGroup
            case bandwidthThrottling
            case createPublicIP
            case dataPlaneRouting
            case defaultLargeStagingDiskType
            case ebsEncryption
            case ebsEncryptionKeyArn
            case name
            case pitPolicy
            case replicatedDisks
            case replicationServerInstanceType
            case replicationServersSecurityGroupsIDs
            case sourceServerID
            case stagingAreaSubnetId
            case stagingAreaTags
            case useDedicatedReplicationServer
        }
    }

    public struct UpdateReplicationConfigurationTemplateRequest: AWSEncodableShape {
        /// The Replication Configuration Template ARN.
        public let arn: String?
        /// Whether to associate the default Elastic Disaster Recovery Security group with the Replication Configuration Template.
        public let associateDefaultSecurityGroup: Bool?
        /// Configure bandwidth throttling for the outbound data transfer rate of the Source Server in Mbps.
        public let bandwidthThrottling: Int64?
        /// Whether to create a Public IP for the Recovery Instance by default.
        public let createPublicIP: Bool?
        /// The data plane routing mechanism that will be used for replication.
        public let dataPlaneRouting: ReplicationConfigurationDataPlaneRouting?
        /// The Staging Disk EBS volume type to be used during replication.
        public let defaultLargeStagingDiskType: ReplicationConfigurationDefaultLargeStagingDiskType?
        /// The type of EBS encryption to be used during replication.
        public let ebsEncryption: ReplicationConfigurationEbsEncryption?
        /// The ARN of the EBS encryption key to be used during replication.
        public let ebsEncryptionKeyArn: String?
        /// The Point in time (PIT) policy to manage snapshots taken during replication.
        public let pitPolicy: [PITPolicyRule]?
        /// The Replication Configuration Template ID.
        public let replicationConfigurationTemplateID: String
        /// The instance type to be used for the replication server.
        public let replicationServerInstanceType: String?
        /// The security group IDs that will be used by the replication server.
        public let replicationServersSecurityGroupsIDs: [String]?
        /// The subnet to be used by the replication staging area.
        public let stagingAreaSubnetId: String?
        /// A set of tags to be associated with all resources created in the replication staging area: EC2 replication server, EBS volumes, EBS snapshots, etc.
        public let stagingAreaTags: [String: String]?
        /// Whether to use a dedicated Replication Server in the replication staging area.
        public let useDedicatedReplicationServer: Bool?

        public init(arn: String? = nil, associateDefaultSecurityGroup: Bool? = nil, bandwidthThrottling: Int64? = nil, createPublicIP: Bool? = nil, dataPlaneRouting: ReplicationConfigurationDataPlaneRouting? = nil, defaultLargeStagingDiskType: ReplicationConfigurationDefaultLargeStagingDiskType? = nil, ebsEncryption: ReplicationConfigurationEbsEncryption? = nil, ebsEncryptionKeyArn: String? = nil, pitPolicy: [PITPolicyRule]? = nil, replicationConfigurationTemplateID: String, replicationServerInstanceType: String? = nil, replicationServersSecurityGroupsIDs: [String]? = nil, stagingAreaSubnetId: String? = nil, stagingAreaTags: [String: String]? = nil, useDedicatedReplicationServer: Bool? = nil) {
            self.arn = arn
            self.associateDefaultSecurityGroup = associateDefaultSecurityGroup
            self.bandwidthThrottling = bandwidthThrottling
            self.createPublicIP = createPublicIP
            self.dataPlaneRouting = dataPlaneRouting
            self.defaultLargeStagingDiskType = defaultLargeStagingDiskType
            self.ebsEncryption = ebsEncryption
            self.ebsEncryptionKeyArn = ebsEncryptionKeyArn
            self.pitPolicy = pitPolicy
            self.replicationConfigurationTemplateID = replicationConfigurationTemplateID
            self.replicationServerInstanceType = replicationServerInstanceType
            self.replicationServersSecurityGroupsIDs = replicationServersSecurityGroupsIDs
            self.stagingAreaSubnetId = stagingAreaSubnetId
            self.stagingAreaTags = stagingAreaTags
            self.useDedicatedReplicationServer = useDedicatedReplicationServer
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, max: 2048)
            try self.validate(self.arn, name: "arn", parent: name, min: 20)
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:.{16,2044}$")
            try self.validate(self.bandwidthThrottling, name: "bandwidthThrottling", parent: name, min: 0)
            try self.validate(self.ebsEncryptionKeyArn, name: "ebsEncryptionKeyArn", parent: name, max: 2048)
            try self.validate(self.ebsEncryptionKeyArn, name: "ebsEncryptionKeyArn", parent: name, min: 20)
            try self.validate(self.ebsEncryptionKeyArn, name: "ebsEncryptionKeyArn", parent: name, pattern: "^arn:.{16,2044}$")
            try self.pitPolicy?.forEach {
                try $0.validate(name: "\(name).pitPolicy[]")
            }
            try self.validate(self.pitPolicy, name: "pitPolicy", parent: name, max: 10)
            try self.validate(self.pitPolicy, name: "pitPolicy", parent: name, min: 1)
            try self.validate(self.replicationConfigurationTemplateID, name: "replicationConfigurationTemplateID", parent: name, max: 21)
            try self.validate(self.replicationConfigurationTemplateID, name: "replicationConfigurationTemplateID", parent: name, min: 21)
            try self.validate(self.replicationConfigurationTemplateID, name: "replicationConfigurationTemplateID", parent: name, pattern: "^rct-[0-9a-zA-Z]{17}$")
            try self.validate(self.replicationServerInstanceType, name: "replicationServerInstanceType", parent: name, max: 255)
            try self.replicationServersSecurityGroupsIDs?.forEach {
                try validate($0, name: "replicationServersSecurityGroupsIDs[]", parent: name, max: 255)
                try validate($0, name: "replicationServersSecurityGroupsIDs[]", parent: name, pattern: "^sg-[0-9a-fA-F]{8,}$")
            }
            try self.validate(self.replicationServersSecurityGroupsIDs, name: "replicationServersSecurityGroupsIDs", parent: name, max: 32)
            try self.validate(self.stagingAreaSubnetId, name: "stagingAreaSubnetId", parent: name, max: 255)
            try self.validate(self.stagingAreaSubnetId, name: "stagingAreaSubnetId", parent: name, pattern: "^subnet-[0-9a-fA-F]{8,}$")
            try self.stagingAreaTags?.forEach {
                try validate($0.key, name: "stagingAreaTags.key", parent: name, max: 256)
                try validate($0.value, name: "stagingAreaTags[\"\($0.key)\"]", parent: name, max: 256)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case associateDefaultSecurityGroup
            case bandwidthThrottling
            case createPublicIP
            case dataPlaneRouting
            case defaultLargeStagingDiskType
            case ebsEncryption
            case ebsEncryptionKeyArn
            case pitPolicy
            case replicationConfigurationTemplateID
            case replicationServerInstanceType
            case replicationServersSecurityGroupsIDs
            case stagingAreaSubnetId
            case stagingAreaTags
            case useDedicatedReplicationServer
        }
    }
}

// MARK: - Errors

/// Error enum for Drs
public struct DrsErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case conflictException = "ConflictException"
        case internalServerException = "InternalServerException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case serviceQuotaExceededException = "ServiceQuotaExceededException"
        case throttlingException = "ThrottlingException"
        case uninitializedAccountException = "UninitializedAccountException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize Drs
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// You do not have sufficient access to perform this action.
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    /// The request could not be completed due to a conflict with the current state of the target resource.
    public static var conflictException: Self { .init(.conflictException) }
    /// The request processing has failed because of an unknown error, exception or failure.
    public static var internalServerException: Self { .init(.internalServerException) }
    /// The resource for this operation was not found.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// The request could not be completed because its exceeded the service quota.
    public static var serviceQuotaExceededException: Self { .init(.serviceQuotaExceededException) }
    /// The request was denied due to request throttling.
    public static var throttlingException: Self { .init(.throttlingException) }
    /// The account performing the request has not been initialized.
    public static var uninitializedAccountException: Self { .init(.uninitializedAccountException) }
    /// The input fails to satisfy the constraints specified by the AWS service.
    public static var validationException: Self { .init(.validationException) }
}

extension DrsErrorType: Equatable {
    public static func == (lhs: DrsErrorType, rhs: DrsErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension DrsErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
